簡體   English   中英

在Python中導入庫類

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM