2016-12-30 73 views
1

所以,編程在Python 3,我有一個程序,其實質我蒸餾水在這個(非)功能的代碼問題:Python對象交互

class One: 
    def __init__(self): 
     self.var1 = 1 

    def change(self): 
     two.var2 = 5 

class Two: 
    def __init__(self): 
     one = One() 
     self.var2 = 2 
     one.change() 

two = Two() 

的IDLE解釋拋出:

> Traceback (most recent call last): 
    File "C:/-", line 15, in <module> 
    two = Two() 
    File "C:/-", line 12, in __init__ 
    one.change() 
    File "C:/-", line 6, in change 
    two.var2 = 5 
NameError: name 'two' is not defined 

顯然,這樣做,而不是:

class One: 
    def __init__(self): 
     self.var1 = 1 

    def change(self): 
     two.var2 = 5 

class Two: 
    def __init__(self): 
     self.var2 = 2 
     one.change() 

one = One() 
two = Two() 

...沒有幫助,因爲它給我確切的相同類型的錯誤。我真的不明白爲什麼會發生這種情況......或者如何以不同的方式構造它。我想我最後一次遇到這樣的問題時,我通過嵌套類來避免它(相當混亂,只爲了一層嵌套而工作,據我所知),但我真的很想知道如何使這兩個嵌套對象正確地相互溝通。

編輯︰我有一個程序,其唯一的代碼行實例化一個主類,我們稱之爲「地球」。在這個程序對象中,一切都會發生,包括其他類的實例化;讓我們假設在這種情況下它只有一個,稱之爲「月亮」。我想要做的是月亮能夠改變地球的狀態及其不同的變量。

+2

也許試圖解釋你想做什麼可能會幫助我們將你引導到一個解決方案,因爲目前上面的方法看起來有缺陷。 – AChampion

+0

@AChampion同意,這可能是[XY問題](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。 – Aaron3468

回答

1

當我看到它,你只需要傳遞給one.change()你想改變

class One: 
def __init__(self): 
    self.var1 = 1 

def change(self, two): 
    two.var2 = 5 

class Two: 
def __init__(self): 
    self.var2 = 2 
    one.change(self) 


one = One() 
two = Two() 
2

你誤會了python的工作原理。在分配兩個之前,您不能撥打two.var2 = 5。但是你稱之爲,而你正在實例化的two = Two()),所以你正在構建的對象還沒有被分配到two。此外,類訪問全球範圍通常設計較差。

考慮使用依賴注入,在該類中爲類提供所需數據的本地副本。這將採取def __init__(self, dependency): self.dependency = dependency的形式。您甚至可以使用類Two作爲依賴項,創建對象的組合而不是繼承。

我接觸繼承,它似乎是另一種解決方案:也許你的意思是說self.var2 = 5,並讓您的類Two繼承自One

0

哪個對象「你誤會了蟒蛇是如何工作的。」我不會那樣說的;一般來說,我對OOP有一個細緻的把握,而不是專門針對Python。但是,我離題...

「直到二是分配,你不能叫two.var2 = 5,但是你打電話 當你正實例(二=二()),所以對象你是 大樓還沒有分配到兩個,而且,一般來說 的設計不好,因爲這些設計是爲了訪問全球範圍的類。「

我修改了代碼,以反映這一點,或至少是這樣,我的理解是:

class One: 
    def __init__(self): 
     self.var1 = 1 

    def change(self): 
     two.var2 = 5 

class Two: 
    def __init__(self): 
     self.var2 = 2 
     self.program() 

    def program(self): 
     one = One() 
     one.change() 

two = Two() 

我這樣做是想的問題是,在第二個對象的函數調用之前INIT第一個函數的總結,但它仍然不起作用。無論如何,更多的修補,我試過了,這可能是結構化的邏輯方式:

class One: 
    def __init__(self): 
     self.var1 = 1 

    def change(self): 
     two.var2 = 5 

class Two: 
    def __init__(self): 
     self.var2 = 2 

one = One() 
two = Two() 
one.change() 

...它的工作,如預期的那樣。如果最後三行代碼可以成爲我正在使用的「程序對象」的一部分,並且仍然可以正常工作,那麼我會研究它是否可行。或者,也許我可以完全放棄「程序對象」,只要在主類中有幾行代碼就在其外面。

無論如何,我需要的是約瑟夫的解決方案。謝謝!但是你到底在做什麼?通過使用「self」作爲第二個對象方法的參數,你傳遞了什麼?物體」?對它的引用...?

0

你有兩個類的實例想要互相交互。每個實例都可以保留對其他引用的引用,但是循環引用是python的一個詭計,因爲它們可能會混淆引用計數器,並且在不再使用引用計數器時無法刪除對象。

weakref模塊可以讓你保持這些關係而不會搞亂垃圾收集。所以,

import weakref 

class One: 
    def __init__(self, two): 
     self.var1 = 1 
     self.two = weakref.ref(two) 

    def change(self): 
     self.two().var2 = 5 

class Two: 
    def __init__(self): 
     self.one = One(self) 
     self.var2 = 2 
     self.one.change() 

two = Two() 
print(two.var2)