__package__
以允许子模块中的显式相对导入的PEP 366 - 主模块显式相对导入中,有如下摘录:
我尝试在以下场景中使用这个样板文件:When the main module is specified by its filename, then the
__package__
attribute will be set toNone
. To allow relative imports when the module is executed directly, boilerplate similar to the following would be needed before the first relative import statement:
if __name__ == "__main__" and __package__ is None: __package__ = "expected.package.name"
Note that this boilerplate is sufficient only if the top level package is already accessible via
sys.path
. Additional code that manipulatessys.path
would be needed in order for direct execution to work without the top level package already being importable.This approach also has the same disadvantage as the use of absolute imports of sibling modules - if the script is moved to a different package or subpackage, the boilerplate will need to be updated manually. It has the advantage that this change need only be made once per file, regardless of the number of relative imports.
Directory layout:
foo ├── bar.py └── baz.py
Contents of the bar.py submodule:
if __name__ == "__main__" and __package__ is None: __package__ = "foo" from . import baz
PYTHONPATH
修改可使包foo/在sys.path
上可访问):PYTHONPATH=$(pwd) python3 foo/bar.py
使用样板文件时,从模块命名空间执行子模块 bar.py 也是有效的:
python3 -m foo.bar
然而,以下备选文本样板在两种情况下同样适用于bar.py子模块的内容:
if __package__:
from . import baz
else:
import baz
此外,这个替代模板更简单,并且在将其与子模块baz.py一起移动到不同的包中时不需要更新子模块bar.py(因为它不会硬编码包名"foo"
)。
下面是我关于PEP 366模板的问题:
- 第一个子表达式
__name__=="__main__"
是否必要,或者已经被第二个子表达式__package__ is None
所隐含了? - 第二个子表达式
__package__ is None
应该改为not __package__
,以处理__package__
为空字符串的情况(例如从文件系统提供包含目录的子模块__main__.py
执行:PYTHONPATH=$(pwd) python3 foo/
)吗?
foo.baz
和baz
的每个导入,而不仅仅是在foo
内部。您还必须禁止使用任何第三方的baz
模块,以避免名称冲突。这些都是需要考虑的事情。 - MisterMiyagi