2

私のチームはDjangoとの巨大なプロジェクトに取り組んでいます。簡単にするために、ここに問題を説明するための単純なPythonがあります(元の問題には、クラス(両方がクラスであることを知っています)とパッケージ(両方がパッケージであることも知っています)の代わりにモデルとアプリがあります)。

a.py

from b import B1


class A1(object):
    def __init__(self):
        print "object A1"


class A2(object):
    def __init__(self):
        print "object A2"


A1()
B1()

b.py

from a import A2


class B1(object):
    def __init__(self):
        print "object B1"


A2()

a.pyが呼び出されると、bパッケージからB1をインポートしようとします一方、パッケージからA2をインポートしようとする最初から永久に繰り返されます。Pythonは言う:

[dagrevis@localhost recursion]$ python2 a.py
Traceback (most recent call last):
  File "a.py", line 1, in <module>
    from b import B1
  File "/home/dagrevis/Python/recursion/b.py", line 1, in <module>
    from a import A2
  File "/home/dagrevis/Python/recursion/a.py", line 1, in <module>
    from b import B1
ImportError: cannot import name B1

解決策の1つは、オブジェクトごとに1つのファイルを作成することです。C++やJavaのようなものがあります。それから私はGuidoがPythonについて言ったことを思い出しました:「PythonでJava(またはC ++、またはJavascript、...)を書かないでください。」この問題に対処するためのPythonの方法は他にもありますか?

アドバイスありがとうございます!

4

2 に答える 2

4

あなたのユースケースは「解決可能」ではありません。オブジェクトをインポートする代わりに、をモジュールImportErrorのインポート(および)に変えることができますが、これによって、これらのモジュールを使用できなくなるという事実は変わりません。AttributeErrorab

問題は、モジュールをインポートする前aに完全に実行する必要がbあるだけでなく、インポートする前にb完全に実行する必要があるaことです。

これを解決することは単純に不可能であり、リファクタリングが必要であることは明らかです。モジュールは単一のモジュールである必要があります(または、より深いリファクタリングを実行する必要がある場合があります)ab

編集:実際には、これを解決できる可能性がありますが、必要に応じてインポートをファイルの最後に配置することは非常に醜いと思います。しかし、これはいくつかのより大きな問題の単なるパッチになると思います。

于 2012-09-18T10:37:00.643 に答える
2

あなたの例は過度に単純化されています-それは循環インポートが必要な理由を説明していません。しかしとにかく、これは実行可能なコードにリファクタリングする1つの方法です。

a.py:

class A1(object):
    def __init__(self):
        print "object A1"


class A2(object):
    def __init__(self):
        print "object A2"

b.py:

class B1(object):
    def __init__(self):
        print "object B1"

c.py:

from a import A1, A2
from b import B1

A1()
A2()
B1()
于 2012-09-18T10:43:43.493 に答える