tl;博士:
我喜欢干净的API,所以我不喜欢有";内部";导入,如模块内部的import numpy as np
,显示在模块API中。
在我的软件包(可使用setup.py安装(中,我有几个子模块,每个子模块都导入一组模块,例如numpy
或像sys
这样的内置模块
假设在我的包mytools
中,我有一个子模块mytools.mysubtools
,在其中我定义了一个函数foo
,它需要numpy
(与import numpy as np
一起导入(。CCD_ 9被添加到CCD_
现在我用import mytools.mysubtools as mst
导入这个子模块。当使用代码完成(例如使用Spyder IDE、PyCharm、Kite…(等访问mst
时,它总是显示mst
中的所有符号和导入,在本例中为foo
和np
我可以避免像np
这样的导入显示在导入的模块中,从而只显示foo
吗?
详细说明
假设我的包结构如下:
/mytools/
|-- __init__.py # "mytools-init"
|-- my_subtools.py
|-- some_other_subtools.py
__init__.py
文件如下所示:
from . import my_subtools as mysubtools
__all__ = ['mysubtools']
和my_subtools.py
:
import numpy as np
__all__ = ['foo']
def foo():
return np.sqrt(4**3)
现在我用导入my_subtools
import mytools.mysubtools as mst
当使用导入的模块时,代码补全等总是显示np
和foo
,例如当键入mst.
时。对于较大的模块,有许多导入和/或函数/类定义,这使得很难使用代码完成,因为对API的简单检查会显示所有导入的模块和所有定义。
使用__all__
可以避免导入所有用于通配符/星号导入的符号,如from mytools.mysubtools import *
。__all__
在某种程度上也可以用来破坏显式导入吗?
或者有什么建议的方法可以避免导入模块的所有符号
对于函数,我使用名称篡改,例如def _baz(): return 4**4
但这是否也适用于进口,例如import numpy as _np
?有什么缺点吗?
我正在寻找:
显式解决方案,因为:显式比隐式更好
例如类似__all__
的内容,但用于显式导入。或者类似__except__ = ['np']
的东西,它将符号从导入中排除。
__all__ = [...]
是";"可出口";名字,但这只是一个提示。(不过,PyCharm等一些IDE确实倾向于获得线索。(
我绝对不会做import numpy as _np
;你只会让你的生活更加艰难。
你不能阻止某人从你的模块中导入东西,如果他们在那里。。。如果你真的真的想,你当然可以用del np, sys, os, quux, bar
这样的咒语来后缀你的所有模块;这样这些名字就不重要了,但是。。。我真的认为这不值得付出努力。
感谢@chepner的评论,我一直在研究python标准库中的链接实现。
结论是,导入模块的名称篡改在标准库中被频繁使用。在我看来,这是一个非常明显的迹象,表明这被认为是蟒蛇和/或没有严重的负面影响
可以找到几个名称篡改进口的例子,例如:
- random.py
- 字符串.py
- _pydecimal.py
哪些模块的名称被篡改似乎会随着文件的不同而变化。看起来;系统相关";模块的名称被篡改的可能性就越小。例如等进口产品
import re as _re
import math as _math
经常被篡改名称,而import os as _os
则不太常见。这只是我的印象,所以一般来说可能不是真的。