这是对隐式相对导入的 Python 2 行为 (deprecated since 2.6) 的引用:允许 import bar 在包 foo 中的模块中引用模块 foo.bar .考虑sys.path 上的一个目录,看起来像
…
|-- client.py
`-- pkg
|-- __init__.py
|-- mod.py
`-- script.py
具有以下内容的文件:
client.py
print "client..."
from pkg import mod,script
print "client!"
pkg/__init__.py
print "pkg"
pkg/mod.py
print "mod: %r"%__name__
pkg/script.py
print "script:",__name__,__package__
if __name__=='__main__':
import mod,client
print "script!"
在此设置中mod 可以轻松导入两次:
$ PYTHONPATH=… python …/pkg/script.py
script: __main__ None
mod: 'mod'
client...
pkg
mod: 'pkg.mod'
script: pkg.script None
client!
script!
为了减少配置开销,Python 将目录pkg 添加到sys.path,有效地假定script.py 是顶级模块script。不幸的是,这意味着import mod 创建了一个名为mod 的顶级 模块,然后显式导入pkg.mod 会导致它的另一个副本以其全名存在(就在导入之后pkg 本身)。
这是recognized 造成了问题,后来-m was adjusted 告诉正在执行的模块关于找到它的包,以便相对导入(隐式或显式)正常工作:
$ PYTHONPATH=… python -m pkg.script
pkg
script: __main__ pkg
mod: 'pkg.mod'
client...
script: pkg.script None
client!
script!
请注意,pkg 现在首先被导入(由-m 本身!),script 现在有一个__package__ 属性,而mod 只导入一次。当然,script 它自己 (仍然)被加载了两次,因为它的名称第一次被替换为 __main__,所以 from pkg import script 以不同的名称找到它。
道德是,按照__name__=='__main__' 实现“模块也可以是脚本”从根本上被破坏(和替换have been rejected):模块已经有 em> 一个__name__,并创建一个单独的模块对象作为入口点,以便其__name__ 可以不同,这与复制提供main 的Java 类(及其所有静态数据)一样荒谬。制作一个没有人导入的模块是可行的,但却是矛盾的(并且会破坏导入包的所有成员的代码检查)。