2009-06-25 11 views
6

私はお互いを参照する2つのクラスを持っていますが、明らかにコンパイラは不平を言います。これを回避する方法はありますか?互いに参照するPythonクラス

EDITは、実は私のコードは、ハンク・ゲイが使用するものとは多少異なります。だから、Pythonはいくつかの種類の循環参照を確実に扱うことができますが、以下の状況ではエラーを投げます。以下は私が持っているもので、私は「名前は定義されていないエラー」という名前を得る。助言がありますか。

+4

「明白」とは何ですか?それはどこで不平を言うのですか?コードを表示しますか? Pythonでは循環参照は問題ありませんが、問題は他のところにあります。 –

+0

コードはどのように見えますか? –

+0

wow ... * rolleyes * – Robbie

答えて

15

pythonでは、クラスがロードされると、クラス内のコードが実行されます。

今、どういう意味ですか? ;-)

は、次のコードを考えてみましょう:

class x: 
    print "hello" 
    def __init__(self): print "hello again" 

あなたは、コードを含むモジュールをロードすると、Pythonはhelloを印刷します。 xを作成するたびに、pythonはhello againを出力します。

def __init__(self): ...__init__ = lambda self: ...と同等と考えることができますが、pythonのlambda制限は適用されません。つまり、defは代入であり、なぜメソッドの外側のコードが実行されるのかを説明するかもしれません。

あなたのコードはモジュールがロードされたときにYが値を持って前にあなたは、Yを参照してください

class X(models.Model): 
    creator = Registry() 
    creator.register(Y) 

言います。あなたは割り当てとしてclass Xと考えることができます(私はオフ手匿名クラスを作成するための構文を覚えていないことができ、多分それはtypeの呼び出しですか?)

あなたがやりたいことは何これです:

class X(models.Model): 
    pass 
class Y(models.Model): 
    foo = something_that_uses_(X) 
X.bar = something_which_uses(Y) 

Yの後にYを参照するXのクラス属性を作成します。または逆の場合:を最初に作成し、次にXを作成し、次にXに依存するYの属性を作成します。

ホープこれは

2

更新:彼は私の答えの後に質問を変更しました。現在受け入れられている解決策は、新しい質問に照らしてより良い方法です。

何が問題なのですか?

class A(object): 
    def __init__(self): 
     super(A, self).__init__() 


    def b(self): 
     return B() 


class B(object): 
    def __init__(self): 
     super(B, self).__init__() 


    def a(self): 
     return A() 

これはうまくコンパイルされ実行されます。

+0

追加情報:これはうまくいきます。しかし、これには価格が付いています。すべてのクラスを1つのファイルにまとめるだけです。これは非常に不便です:それは非常にpythonicかもしれませんが、わかりませんが、私はそれが各(public)クラスのために独自のファイルを使用する良いOOPの練習で壊れていることを知っています。 –

2

メソッド内で作業している間は、クラスオブジェクトにアクセスできます。

creator.register(Y)__init__に移動すると、上記の例は問題ありません。ただし、メソッドの外部にあるクラスへの循環参照はできません。

+1

この回答は何も説明していません。 JonasとJohn Machinの答えで説明されている、実際の問題を理解したり説明したりせずに「回避策」を提供します。 –

2

エラーがcreator.register(Y)の実行は、クラスXの(実行可能な)定義中に試みられている:)役立ち、その段階では、クラスYが定義されていません。これを理解する:classdefは、実行される文(通常はインポート時)です。彼らは「宣言」ではありません。

提案:新しい質問として、達成しようとしていることを教えてください。

-2

問題はPythonではない可能性が高いです。私はそれがSQLの問題だと思うだろう。クラスは抽象レイヤーを介してSQLクエリーに変換され、テーブルが作成されます。 その時点ではまだ存在しないテーブルを別のテーブルから参照しようとしています。

私は、参照することなく、第1のテーブルを作成することによってこの問題を解決し、その後これらの参照を作るためにそれらを変更、

しかし、私は私の答えについてわからないので、調味料の多くとそれを取るでしょうSQLで

Djangoのデータベース抽象化レイヤーが相互参照をうまく扱えない場合、実際には非常に驚くでしょう。

関連する問題