3

重複の可能性:
Python での循環 (または循環) インポート

a.py

import b

class Abstract(object):
    pass

class Concrete(Abstract):
    def get_newthing(self):
        return b.NewThing()

(注: a.py の主要なリファクタリングを行うのは難しいでしょう)

b.py

import a
#reload(a)

class NewThing(a.Abstract):
    pass

書かれているように、「import b、a」を実行すると機能しますが、「import a」を実行すると

AttributeError: 'module' object has no attribute 'Abstract' 

Python が a.py の「import b」行に到達すると、b のインポート中に、まだ作成されていない「a.Abstract」にアクセスしようとします。

ただし、reload ステートメントを含めると、Python が a.py モジュールに戻り、b.py に進む前に Abstract クラスを作成するため、"import a" を問題なく実行できます。したがって、うまくいくようです(ただし、リロードを行う前に hasattr チェックを追加する必要があります)。

このインポート ループの問題を解決する方法を探していましたが、これらの提案に沿った提案は見当たりませんでした。このように reload() を使用する際に落とし穴はありますか?

4

2 に答える 2

0

これには使用しないでくださいreload。対話型プロンプトでのみ使用します。この循環性は次のように修正できます。

class Abstract(object):
    pass

class Concrete(Abstract):
    def get_newthing(self):
        import b
        return b.NewThing()

循環インポートが必要ないように、コードをリファクタリングすることをお勧めします。

于 2012-12-15T02:22:15.180 に答える
0

あなたのモジュールの設計a.pyは非常に悪いです。通常は避けるべき循環インポートが必要になります。最良の解決策は、Concreteクラス (およびimport bそれが必要とする行) を別のモジュールに分割することaですb

ただし、状況に対してリファクタリングが多すぎる場合は、import b行を の上部からa.pyの定義の下に移動してみてくださいAbstract。これにより、NewThingが常にAbstractの定義を確認できるようになるため、発生しているエラーが修正されます。

つまり、次のようにします。

class Abstract(object):
    pass

import b

class Concrete(Abstract):
    def get_newthing(self):
        return b.NewThing()

これは最小限の変更ですが、この状況では機能するはずです。Concreteただし、定義時にクラスへのアクセスが必要な場合NewThingは、この方法で修正することはできません。

于 2012-12-15T02:39:37.800 に答える