3

谷歌 Python 风格指南

不要在导入中使用相对名称。即使模块在同一个包中,也要使用完整的包名。这有助于防止无意中两次导入包。

什么是导致两次导入包的示例设置?

4

1 回答 1

3

这是对隐式相对导入的 Python 2 行为(自 2.6 起已弃用)的引用:允许包中的模块引用该模块。考虑一个看起来像的目录import barfoofoo.barsys.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 将目录添加pkgsys.path,有效地假定这script.py是一个顶级模块script。不幸的是,这意味着import mod创建了一个名为 的顶级模块mod,而对 later 的显式导入pkg.mod会导致它的另一个副本以其全名存在(仅在导入pkg自身之后)。

认识到这会带来问题,后来-m 进行了调整,以告知正在执行的模块有关在哪个包中找到它的信息,以便相对导入(隐式或显式)正常工作:

$ 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__'是被破坏的(并且替换已被拒绝):一个模块已经一个__name__,并创建一个单独的模块对象作为入口点,以便它__name__可以不同就像复制提供main. 制作一个没有人导入的模块是可行的,但却是矛盾的(并且会破坏导入包所有成员的代码检查)。

于 2022-01-13T23:42:42.600 回答