[英]Google Python Style Guide & relative imports
谷歌 Python 風格指南 說:
不要在導入中使用相對名稱。 即使模塊在同一個 package 中,也要使用完整的 package 名稱。 這有助於防止意外導入 package 兩次。
導致導入 package 兩次的示例設置是什么?
這是對隱式相對導入的 Python 2 行為(自 2.6 起已棄用)的引用:允許 package foo
中的模塊中的import bar
引用模塊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
本身之后)。
認識到這會帶來問題,后來調整了-m
以告訴正在執行的模塊關於 package 的發現,以便相對導入(隱式或顯式)正常工作:
$ 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__
,並創建一個單獨的模塊 object 作為入口點使其__name__
可以不同,這與復制提供main
的 Java class (及其所有 static 數據)一樣荒謬。 制作一個沒有人導入的模塊是可行的,但卻是矛盾的(並且會破壞導入包所有成員的代碼檢查)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.