仅使模块中的特定符号可导入,例如使用`__all__`



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中的所有符号导入,在本例中为foonp
我可以避免像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

当使用导入的模块时,代码补全等总是显示npfoo,例如当键入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则不太常见。这只是我的印象,所以一般来说可能不是真的。

最新更新