【问题标题】:Python - How can I make 2 objects reference one another? (Circular dependancy)Python - 如何让 2 个对象相互引用? (循环依赖)
【发布时间】:2020-04-26 19:19:39
【问题描述】:

这是我的问题:我想要 2 个单个对象来引用和更新彼此的属性。

所以,我尝试这样做(我正在下棋):

 # white.py
 class White(object):
 ...
      def move_white_piece(self):
           from black import Black
           black_object = Black()
           # ...

我在函数内部导入的原因是,如果不这样做,就会发生循环依赖(即,自从首先声明了 White 以来,White 还不知道 Black)。这修复了 AttributeError(现在定义了类)。但是,这带来了一个新问题,现在我每次都在函数内部使用一个新对象(因此不是当前属性)。我需要在整个程序中使用单个对象。这可能吗?

由于前向声明和原型,我在 C++ 中从未遇到过这个问题。

【问题讨论】:

  • 附带说明:Black 是类的名称。然后实例化该类的一个实例并将其分配给名为Black 的变量,从而重新定义Black 的含义。这将是您将创建的Black 类的最后一个对象。你明白我的意思吗?类名通常大写,变量名通常以小写开头。如果您遵循该约定,您将避免 那个 问题。
  • 是的,已更改以解决混淆问题。
  • 看我的回答;我只为整个程序运行创建一个黑色块。

标签: python oop


【解决方案1】:

我不太确定拥有两个相互引用的对象总是不好。尽管如此,我发现不寻常的是,您正在一个名为move_white_piece 的方法中为黑色块创建一个实例。当然,这是要重复调用的方法。你是否打算在每次白人必须采取行动时创造一个新的黑色棋子?这对我来说意义不大。更有意义的是:

from black import Black

class White:

    def __init__(self):
        self.black_piece = Black() # create black piece when we are created
        black_piece.set_white_piece(self) # give black piece a reference to ourself

    def move_white_piece(self):
        # whatever

然后是黑色班:

class Black:

     def set_white_piece(self, white_piece):
         self.white_piece = white_piece

另一种风格:

class White:

    def __init__(self):
        self.black_piece = Black(self) # create black piece when we are created

    def move_white_piece(self):
        pass

class Black:
    def __init__(self, white_piece):
        self.white_piece = white_piece

这是品味和/或要求的问题。

但坚持住,因为还有更多:

除非您有非常特殊的理由这样做,否则如果两个彩色棋子的规则和策略完全相同,则不应有单独的类 BlackWhite,例如在标准的国际象棋游戏中。当然,一种颜色必须先移动,然后从该点开始交替移动。但只要你在实现一个黑白规则和策略相同的游戏,黑白应该只是同一类的两个实例。

【讨论】:

  • 刚刚添加了我为什么要导入内部函数的说明。其他答案说这是处理相互进口的方式,即stackoverflow.com/questions/1250103/…
  • 我的问题不是你在哪里导入;你的每一个动作都创造新作品:black_object = Black()。而且没有理由不能将该导入移动到文件顶部,是吗?
  • 问题是这些只是整个程序中的2个类。我的主代码文件夹包含一个 common.py 文件,其中包含我所有的导入和类声明。所以,在white.py 和我所有其他课程的顶部,我将有from common import * 这一行。因此,您可以想象,由于我首先在common.py 中导入和声明 Black 类,因此会发生循环导入。为了解决这个问题,我只需再次在我的函数中导入,这样类就被定义了,但是多对象问题就会成为一个问题。
  • 不,我无法想象。 White 类需要先查看 Black 的定义,然后才能执行 self.black_piece = Black()。但是Black 类不需要查看White 的任何定义就能够编译我在答案中显示的内容。 Python 不是 C++。
  • 非常感谢这个答案,我会试试看它是否有效。顺便说一句:在另一种样式中,您的意思是把括号放在class Black(): 中吗?还是您的意思是class Black:
猜你喜欢
  • 2011-09-18
  • 2014-07-27
  • 2021-09-19
  • 2014-12-18
  • 1970-01-01
  • 1970-01-01
  • 2017-10-12
  • 2021-09-01
  • 2013-10-21
相关资源
最近更新 更多