[英]Importing library classes in Python
我有以下項目層次結構:
project_dir
lib
__init__.py
...
some_script.py
...
agent
__init__.py
...
errors.py
some_agent_script.py
...
lib / agent / erros.py中有SomeException類定義我使用以下代碼將它們導入lib / agent / some_agent_script.py中:
from errors import SomeException
我還使用以下代碼在lib / some_script.py中導入
from agent.errors import SomeException
問題是當我在lib / agent / some_agent_script.py中引發SomeException時,lib / some_script.py無法在except塊中捕獲它:
try:
# Here comes a call to lib/agent/some_agent_script.py function
# that raises SomeException
except SomeException, exc:
# Never goes here
print(exc)
except Exception, exc:
print(exc.__class__.__name__) # prints "SomeException"
# Let's print id's
print(id(exc.__class__))
print(id(SomeException))
# They are different!
# Let's print modules list
pprint.pprint(sys.modules)
我可以在sys.modules中看到erros模塊被導入了兩次:第一個是'agent.errors'鍵,第二個是'lib.agent.errors'鍵
以下代碼是正確的,但它不是一個漂亮的解決方案:
agent_errors = sys.modules.get('agent.errors')
from agent_errors import SomeException
try:
# Here comes a call to lib/agent/some_agent_script.py function
except SomeException:
print('OK')
我該怎么做才能讓這個模塊不要導入兩次?
您應始終使用完全限定的導入。
from lib.agent.errors import SomeException
在每個使用它的模塊中執行此操作。 然后它將始終具有相同的包名稱。 您可能還應該更改頂級包名稱。 名稱“lib”太通用了。
如果您碰巧將模塊命名為基本模塊或“庫存”模塊,這也可以為您節省一些麻煩。 例如,假設您創建了一個模塊lib/agent/socket.py
並在lib/agent/some_agent_script.py
編寫了import socket
。 你實際上不會得到你的模塊,而是股票。
因此,如果可以的話,最好養成使用完全限定的軟件包名稱的習慣。
另一種方法是使用絕對進口。
from __future__ import absolute_import
import .errors
注意前導點。 這顯式從當前包導入。 它也應該解決你的問題,但我承認我沒有嘗試過。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.