Python 对象交互

Python object interaction

所以,在 Python 3 中编程,我得到了一个有问题的程序,我在这段(非)功能代码中提取了它的本质:

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()

...没有帮助,因为它给了我完全相同类型的错误。我真的不明白为什么会这样……或者如何以不同的方式构建它。我想上次我遇到这样的问题时,我通过嵌套 classes 避免了它(据我所知,相当混乱,只为一层嵌套工作),但我真的很想知道如何让这两个对象正常通信。

编辑: 我有一个程序,它的唯一代码行实例化了一个主 class,我们称它为 "Earth"。在这个程序对象中,一切都会发生,包括其他 classes 的实例化;我们假设在这种情况下只有一个,并将其命名为 "Moon"。我想要做的是让这个物体 Moon 能够改变地球的状态,它的不同变量。

您误解了 python 的工作原理。在分配两个之前,您不能调用 two.var2 = 5。但是您在实例化 (two = Two()) 时调用 ,因此您正在构建的对象尚未分配给 two。此外,classes 访问全局范围通常是糟糕的设计。

考虑使用依赖注入,在其中为 class 提供所需数据的本地副本。这将采用 def __init__(self, dependency): self.dependency = dependency 的形式。您甚至可以使用 class Two 作为依赖项,创建对象的组合而不是继承。

我谈到了继承,它似乎是另一种解决方案:也许你的意思是说 self.var2 = 5,并让你的 class Two 继承自 One

如我所见,您只需将要更改的对象传递给 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()

"You've misunderstood how python works."我不会那样说的;总体而言,我对 OOP 了解甚少,具体而言 Python 并不了解。但我离题了...

"Until two is assigned, you cannot call two.var2 = 5. But you call that while you are instantiating (two = Two()), so the object you are building hasn't yet been assigned to two. Furthermore, it is generally poor design for classes to be accessing global scope."

我编辑了我的代码以反映这一点,或者至少是我理解的方式:

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()

...如预期的那样有效。我将对此进行研究,看看如果最后三行代码可以成为我正在使用的 "program-object" 的一部分并且仍然可以正常工作,它是否可以工作。或者,也许我可以完全废弃 "program-object",只在主 class 之外保留几行代码。

无论如何,我需要的是 Josef 的解决方案。谢谢!但是你到底在做什么?通过使用 "self" 作为第二个对象方法的参数,你传递了什么? "object"?对它的引用...?

您有两个 类 实例想要相互交互。每个实例都可以保留对另一个实例的引用,但是循环引用是 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)