2016-12-30 70 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)