4

私はこのようなパッケージを持っています

package/
    __init__.py
    subpackage1/
        __init__.py
        moduleA.py
        moduleB.py
        moduleC.py
        moduleD.py
    subpackage2/
       __init__.py
       moduleX.py
       moduleY.py
       moduleZ.py

moduleB.pyで、インポートしています

from moduleA import bar

moduleAでは、インポートしています

from moduleB import foo

ImportErrorが発生しています。

ImportError: cannot import name foo

ここで何が問題になる可能性がありますか?この問題を回避するには、どうすればよいですか?そして、私は_ init _ .py pf package、subpackage1、subpackage2に何を書くべきですか?

_ init_.pyのサブパッケージ1

from moduleA import *
from moduleB import *
from moudleC import *
from moudleD import *

_ init_.pyのサブパッケージ2

from moduleX import *
from moduleY import *
from moduleZ import *

_ init_.pyパッケージ_

from subpackage1 import *
from subpackage2 import *

_ init _ .pyファイルに問題はありますか?

編集:インポートを変更しました

moduleB

from .moduleA import bar

moduleA

from .moduleB import foo

それでも、同じインポートエラーが発生します。

ImportError: cannot import name foo

編集

moduleB

def Bar():
    def __init__(self):
        self.foo = Foo()
        self.val = 10
        .
        .

moduleA

def Foo():
    def __init__(self):
        self.bar = Bar()
        self.val = 5
        .
        .   

これをやりたいです。そして、私は両方のクラスを異なるファイルに保持することを主張します。どのようにインポートすればよいですか?

4

2 に答える 2

8

実際には、循環インポートの問題のようです。

あなたのmoduleBは、moduleAをロードしようとする「from moduleA import bar」と言っていますが、moduleAで最初に遭遇するのは「from moduleB import foo」で、moduleBに送り返します。したがって、そこには解決できない循環再帰があります。

通常 (常にではありませんが) 循環インポートは、やり方を再考または再構築する必要があることを示しています。ただし、いくつかの可能な回避策があります。

1 つは、インポート ステートメントを Python ファイルの一番下に移動することです (別の関数内で foo または bar を使用していると仮定すると、ファイルが読み込まれたときにすぐには呼び出されません)。

例えば

#ModuleB.py 
class Bar(object):   
  def __init__(self):
    self.foo = Foo()
    self.val = 10
    .
    .
# at bottom of file
from moduleA import Foo

もう 1 つの方法は、「遅延インポート」パターンと呼ばれる関数内に import ステートメントを配置することです。

#ModuleB.py 
class Bar(object):   
  def __init__(self):
    from moduleA import Foo
    self.foo = Foo()
    self.val = 10

__init__.pyファイルに関するご質問について。空のままにしない理由がわかりません。空の__init__.pyファイルは単に python に「このディレクトリは python パッケージです」と伝え、インポートを許可します。

通常、サブパッケージからモジュールをインポートして利用することにより、プログラムを「実行」するファイルがパッケージ ディレクトリにあります。したがって、そのようなファイル (例: package/main.py) が存在すると仮定すると、インポートは次のようになり、空の__init__.pyファイルだけになります。

#package/main.py
from subpackage1.moduleA import bar  # you can now call bar() directly
from subpackage1 import moduleB  # you can now call foo like: moduleB.foo()
from subpackage2.moduleX import jah 

上記で行っていることは、基本的に各サブパッケージ内のすべてのモジュールのすべての関数と属性を取得し、それらがサブパッケージの関数と属性であるかのように、サブパッケージで直接利用できるようにします (したがって、 and の代わりにimport subpackage1and を呼び出すことができます) .)、しかし、あなたがやろうとしていたことは必ずしもそうではないという印象を受けます。この場合、おそらくそれを行う理由はありません。subpackage1.bar()subpackage.foo()subpackage.moduleA.bar()

subpackage1 のモジュールで subpackage2 の何かを使用する必要がある場合は、この質問への回答を参照してください。 または、python パスにディレクトリを追加する方法をググってください。

于 2012-06-14T08:06:53.270 に答える
2

これは階層の問題ではなく、循環参照の問題です。ファイル A にファイル B をインポートするように、ファイル B にファイル A をインポートするように指示することはできません。相互に依存しているため、円は解決できません。

相互にインポートする必要がないようにファイルを再構築するか (Python は Java ではないことを思い出してください。1 つのファイルに複数のクラスを含めることができます)、インポートの 1 つを関数に移動して、相互にインポートする必要がないようにします。インポート時に実行します。

于 2012-06-14T08:07:00.697 に答える