Can someone explain __all__ in Python?
我越来越多地使用python,并且不断看到在不同的
链接到,但这里没有明确提及,正是使用
例如,
1 2 3 4 5 | __all__ = ['bar', 'baz'] waz = 5 bar = 10 def baz(): return 'baz' |
然后可以像这样导入这些符号:
1 2 3 4 5 6 7 | from foo import * print bar print baz # The following will trigger an exception, as"waz" is not exported by the module print waz |
如果上面的
参考:https://docs.python.org/3.5/tutorial/modules.html importing-from-a-package
注:
它是该模块的公共对象列表,由
我只是想说清楚:
所有其他答案都参考模块。最初的问题在
一般情况下,
其他答案解释了模块的行为。这里详细描述了包的确切行为。
简而言之,包级别的
最大的区别是,当您在包的
另一方面,如果在模块中省略
Explain __all__ in Python?
Ok.
I keep seeing the variable
__all__ set in different__init__.py files.Ok.
What does this do?
Ok.
它从模块中声明语义上"公共"的名称。如果
它还将产生程序性影响:好的。
模块中的
1 | __all__ = ['foo', 'Bar'] |
意味着从模块中导入
1 | from module import * # imports foo and Bar |
文档工具
文档和代码自动完成工具(实际上,应该)也可以检查
来自文档:好的。
The
__init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path.Ok.
In the simplest case,
__init__.py can just be an empty file, but it can also execute initialization code for the package or set the__all__ variable.Ok.
因此,
包通常由可以互相导入的模块组成,但这些模块必须与
1 2 3 4 | package/ |-__init__.py # makes directory a Python package |-module_1.py |-module_2.py |
在
1 2 | from module_1 import * from module_2 import * |
在
1 | __all__ = ['foo',] |
在
1 | __all__ = ['Bar',] |
现在,您已经提供了一个完整的API,其他人在导入您的包时可以使用它,比如:好的。
1 2 3 | import package package.foo() package.Bar() |
它们不会有您在创建模块时使用的所有其他名称,而这些模块会把
在做了更多的工作之后,也许你已经决定模块太大了,需要拆分。因此,您可以执行以下操作:好的。
1 2 3 4 5 6 7 8 | package/ |-__init__.py |-module_1/ | |-__init__.py | |-foo_implementation.py |-module_2/ |-__init__.py |-Bar_implementation.py |
在每个
1 2 | from foo_implementation import * __all__ = ['foo'] |
和模块的
1 2 | from Bar_implementation import * __all__ = ['Bar'] |
而且,您可以很容易地向API添加您可以在子包级别而不是子包的模块级别管理的内容。如果要向API添加一个新名称,只需更新
1 2 3 | from Bar_implementation import * from Baz_implementation import * __all__ = ['Bar', 'Baz'] |
如果您还没有准备好在顶级API中发布
1 2 3 | from module_1 import * # also constrained by __all__'s from module_2 import * # in the __init__.py's __all__ = ['foo', 'Bar'] # further constraining the names advertised |
如果您的用户知道
1 2 | import package package.Baz() |
但如果他们不知道,其他工具(如pydoc)就不会通知他们。好的。
以后,当
1 2 3 | from module_1 import * from module_2 import * __all__ = ['foo', 'Bar', 'Baz'] |
预混
默认情况下,python将导出不以
1 | import os as _os, sys as _sys |
使用
我在模块开发生命周期的早期亲自编写了一个
标准库中的大多数包也使用
在下列情况下,坚持使用
- 您仍然处于早期开发模式,没有用户,并且不断地调整您的API。
- 也许你确实有用户,但是你有涵盖API的UnitTests,而且你仍然在积极地添加到API中并在开发中进行调整。
装饰设计师
使用
我从大卫比兹利关于包装的演讲中得到了这样一个出口装潢师的想法。这种实现在CPython的传统进口商中似乎很有效。如果您有一个特殊的导入钩子或系统,我不保证,但是如果您采用它,退出是非常简单的-您只需要手动将名称重新添加到
例如,在实用程序库中,您将定义decorator:好的。
1 2 3 4 5 6 7 8 9 | import sys def export(fn): mod = sys.modules[fn.__module__] if hasattr(mod, '__all__'): mod.__all__.append(fn.__name__) else: mod.__all__ = [fn.__name__] return fn |
然后,在定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | $ cat > main.py from lib import export __all__ = [] # optional - we create a list if __all__ is not there. @export def foo(): pass @export def bar(): 'bar' def main(): print('main') if __name__ == '__main__': main() |
无论是作为主函数运行还是由另一个函数导入,这都可以很好地工作。好的。
1 2 3 4 5 6 | $ cat > run.py import main main.main() $ python run.py main |
使用
1 2 3 4 5 6 7 8 9 10 11 | $ cat > run.py from main import * foo() bar() main() # expected to error here, not exported $ python run.py Traceback (most recent call last): File"run.py", line 4, in <module> main() # expected to error here, not exported NameError: name 'main' is not defined |
好啊。
它还更改了pydoc将显示的内容:
模1.Py
1 2 3 | a ="A" b ="B" c ="C" |
模块2.Py
1 2 3 4 5 | __all__ = ['a', 'b'] a ="A" b ="B" c ="C" |
$ PyDOC模块1
1 2 3 4 5 6 7 8 9 10 11 12 | Help on module module1: NAME module1 FILE module1.py DATA a = 'A' b = 'B' c = 'C' |
$ PyDOC模块2
1 2 3 4 5 6 7 8 9 10 11 12 | Help on module module2: NAME module2 FILE module2.py DATA __all__ = ['a', 'b'] a = 'A' b = 'B' |
我在我的所有模块中声明
来自(非官方)python参考wiki:
The public names defined by a module are determined by checking the module's namespace for a variable named
__all__ ; if defined, it must be a sequence of strings which are names defined or imported by that module. The names given in__all__ are all considered public and are required to exist. If__all__ is not defined, the set of public names includes all names found in the module's namespace which do not begin with an underscore character ("_").__all__ should contain the entire public API. It is intended to avoid accidentally exporting items that are not part of the API (such as library modules which were imported and used within the module).
模块是要导入的
包是一个带有
1 2 3 4 5 6 7 | """ cheese.py - an example module""" __all__ = ['swiss', 'cheddar'] swiss = 4.99 cheddar = 3.99 gouda = 10.99 |
请参见如何将
1 2 3 4 5 6 7 | >>> from cheese import * >>> swiss, cheddar (4.99, 3.99) >>> gouda Traceback (most recent call last): File"<stdin>", line 1, in <module> NameError: name 'gouda' is not defined |
如果没有
1 2 3 | >>> import cheese >>> cheese.swiss, cheese.cheddar, cheese.gouda (4.99, 3.99, 10.99) |
从模块导入名称
1 2 3 | >>> from cheese import swiss, cheddar, gouda >>> swiss, cheddar, gouda (4.99, 3.99, 10.99) |
将模块作为localname导入
1 2 3 | >>> import cheese as ch >>> ch.swiss, ch.cheddar, ch.gouda (4.99, 3.99, 10.99) |
包装
在包的
下面是python mysql connector
1 2 3 4 5 6 7 8 9 10 11 12 13 | __all__ = [ 'MySQLConnection', 'Connect', 'custom_error_exception', # Some useful constants 'FieldType', 'FieldFlag', 'ClientFlag', 'CharacterSet', 'RefreshOption', 'HAVE_CEXT', # Error handling 'Error', 'Warning', ...etc... ] |
默认情况下,包的星号没有
If
__all__ is not defined, the statementfrom sound.effects import * does not import all submodules from the packagesound.effects into the current namespace; it only ensures that the packagesound.effects has been imported (possibly running any initialization code in__init__.py ) and then imports whatever names are defined in the package. This includes any names defined (and submodules explicitly loaded) by__init__.py . It also includes any submodules of the package that were explicitly loaded by previous import statements.
Wildcard imports ... should be avoided as they [confuse] readers and many automated tools.
[PEP 8,@toolmakersteve]
简短回答
考虑这个例子:
1 2 3 | foo ├── bar.py └── __init__.py |
在
(隐式)如果我们不定义
__all__ ,那么from foo import * 将只导入foo/__init__.py 中定义的名称。(明确)如果我们定义
__all__ = [] ,那么from foo import * 将不导入任何内容。(明确)如果我们定义
__all__ = [ ,那么, ... ] from foo import * 将只导入这些名称。
注意,在隐式情况下,python不会导入以
您可以在这里查看python文档。
以下是python语言参考中的相关摘录:
The public names defined by a module are determined by checking the module’s namespace for a variable named
__all__ ; if defined, it must be a sequence of strings which are names defined or imported by that module. The names given in__all__ are all considered public and are required to exist. If__all__ is not defined, the set of public names includes all names found in the module’s namespace which do not begin with an underscore character ('_').__all__ should contain the entire public API. It is intended to avoid accidentally exporting items that are not part of the API (such as library modules which were imported and used within the module).
PEP 8使用了类似的措辞,尽管它也清楚地表明,当缺少
To better support introspection, modules should explicitly declare the names in their public API using the
__all__ attribute. Setting__all__ to an empty list indicates that the module has no public API.[...]
Imported names should always be considered an implementation detail. Other modules must not rely on indirect access to such imported names unless they are an explicitly documented part of the containing module's API, such as
os.path or a package's__init__ module that exposes functionality from submodules.
此外,如其他答案所指出的,
The import statement uses the following convention: if a package’s
__init__.py code defines a list named__all__ , it is taken to be the list of module names that should be imported whenfrom package import * is encountered.
除了现有的答案,