2012-09-30 35 views
0

我在同一模塊中定義兩個類和想使用的第一個第二個(一個全局變量):對象不能在全球範圍內創建,但可以在本地蟒蛇

class Class1(object): 
    global_c2 = Class2() 

    def foo(self): 
     local_c2 = Class2() 

class Class2(object): 
    pass 

global_c2得到一個錯誤但local_c2不。這是有道理的,因爲當編譯器查看這個文件時,它不會知道Class2將會存在。此外,如果我切換類,以便Class2首先定義它的作品。

但是我想知道是否有另一種方法來解決這個問題。也許我可以通過某種方式告訴python Class2將會存在,所以不用擔心,或者我只需要將它們按正確的順序排列?

+0

正確縮進您的代碼。 –

+0

@AshwiniChaudhary正確縮進。那麼,'self'參數暗示'foo'是作爲一種方法的意圖,但它無論哪種方式都有效,並且無論如何都能很好地說明問題。 – delnan

+0

函數foo()'屬於哪裏? –

回答

1

編譯器不會做任何事情在這裏。在這兩種情況下,完全相同的字節碼序列生成

運行語句的原因是什麼?Python模塊中的所有代碼都是從底層執行 - 沒有聲明這樣的東西,一切都是定義並且每個綁定都是動態的。類定義中的代碼在遇到類定義時運行(並且,在之前第二類被帶入並且綁定到名稱Class2)。當函數被調用時,函數中的代碼會運行,並且因爲在第二個類的定義之前不調用該函數,所以在您調用該函數時可用。

這基本上是每個解決方案歸結爲:延遲綁定,直到你綁定的任何東西存在。

+0

謝謝,這是我正在尋找的解釋。我希望可以在__init__文件中聲明Classes,但我認爲「沒有聲明這樣的東西」意味着這是不可能的。謝謝 – Paul

+0

其實,你不應該把「沒有聲明這樣的東西」從字面上看 - 這是事實,你不必爲這些聲明變量或類型,而是一個類,甚至是一個函數體_is_聲明所有效果。 – jsbueno

+1

此外,Django框架在人們構建面向關係的對象模型時遇到了這個問題,因此選擇了這種解決方案:它確實允許對尚未聲明的類的字符串引用(例如, attr =「Class2」')而不是'attr = Class2')。在使用屬性時,如果它的類型是字符串,它將獲得對模塊上具有該名稱的實際類的引用。 – jsbueno

1

你可以做以下(即回填一旦Class2中已申報Class1的內容。

class Class1(object): 
    pass 

class Class2(object): 
    pass 

Class1.global_c2 = Class2() 
+0

-1這不是問題。 – delnan

+0

@delnan這可以解決循環依賴問題 - 感謝downvote: -/ –

+0

OP描述了一個解決方案。這裏也沒有循環依賴。問題是一個完全不同的問題,即*爲什麼*以及何時這是或不是問題。 – delnan