2012-11-02 12 views
5

でライブラリのクラスをインポートします。 PY:私はプロジェクト階層を以下しているのPython

from errors import SomeException 

また、私はlibに/ some_script.py

from agent.errors import SomeException 
にインポートするには、次のコードを使用します

問題は、私はlibに/エージェント/ some_agent_script.pyでSomeExceptionを上げたときに、その後のlib/some_script.pyがブロック以外でそれをキャッチすることはできませんです。

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) 

私はモジュールをerros sys.modulesに見ることができます二回インポートされた:最初は「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') 

このモジュールを2回インポートしないようにするにはどうすればよいですか?

+0

Pythonのバージョンは何ですか? –

+0

It's Python 2.6.6 – fey

+2

関連する読者:[SO質問](http://stackoverflow.com/questions/1459236/module-reimported-if-imported-from-different-path)、[PEP 395](http: /www.python.org/dev/peps/pep-0395/) –

答えて

2

常に完全修飾インポートを使用する必要があります。

from lib.agent.errors import SomeException 

これを使用するすべてのモジュールでこれを行います。それからそれは常に同じパッケージ名を持ちます。 おそらくトップレベルのパッケージ名を変更するべきでしょう。名前 "lib"はあまりにも一般的です。

これは、モジュールの名前をベース、すなわち "ストック"モジュールと同じようにすると、頭痛を軽減します。たとえば、モジュールlib/agent/socket.pyを作成し、lib/agent/some_agent_script.pyimport socketと書き込んだとします。モジュールは実際には得られませんが、在庫は得られません。

したがって、できる限り共通のルートから完全に修飾されたパッケージ名を使用する方がよいです。

代わりに、絶対インポートを使用することができます。

from __future__ import absolute_import 

import .errors 

先頭のドットに注意してください。これは、現在のパッケージから明示的にインポートされます。それはあなたの問題を解決するはずですが、私はそれを試していないことを認めます。

+0

いいですが、lib/agentはいくつかのプロジェクトで使用されているライブラリです。完全修飾名を指定するのは良いことではありません。原因は他のプロジェクトのエージェントがlibモジュールにないことが原因です。 – fey

+0

@fy私は別の方法で私の答えを更新しました。 – Keith

+0

ありがとう!それは私が必要とするものです!追加があります:両方のモジュールでabsolute_importを使用することは例外です。これは例外を発生させ、処理しています。 – fey

関連する問題