我有两个班,B和C.
我想用C引用实例化B,用B引用实例化。
我可以添加一个setter方法,但想知道我是否可以在 init 阶段或任何其他优雅方式中执行此操作
答案 0 :(得分:2)
由于鸡肉和鸡蛋的情况,在__init__
范围内是不可能的。但是,可以在一个赋值语句中使用:
>>> class A:
... pass
...
>>> class B:
... pass
...
>>> a, b = b.a, a.b = A(), B()
>>> a.b is b
True
>>> b.a is a
True
这依赖于Python从左到右评估分配的事实。
是not thread safe;如果您需要保证引用存在于线程应用程序中,那么您将要使用互斥锁来处理可能的竞争条件。 GIL在操作码级别工作,这是一个比Python代码行更精细的分辨率。
答案 1 :(得分:1)
如果您让其中一个类初始值设定项获取另一个类的对象,则可以在__init__
中执行此操作:
>>> class B:
... def __init__(self):
... self.c = C(self)
...
>>> class C:
... def __init__(self, b):
... self.b = b
...
>>> b = B()
>>> c = b.c
>>> b.c
<__main__.C object at 0x107a4f6d8>
>>> b.c.b.c
<__main__.C object at 0x107a4f6d8>
>>> b.c.b.c.b
<__main__.B object at 0x107a60e80>
>>> b
<__main__.B object at 0x107a60e80>
>>> c
<__main__.C object at 0x107a4f6d8>
>>> c.b
<__main__.B object at 0x107a60e80>
>>> b.c
<__main__.C object at 0x107a4f6d8>
>>> b.c.b.c
<__main__.C object at 0x107a4f6d8>
>>> c.b.c.b
<__main__.B object at 0x107a60e80>
甚至没有__init__
的任何论据:
>>> class B:
... def __init__(self):
... self.c = C()
... self.c.b = self
...
>>> class C:
... pass
...
>>> b = B()
>>> c = b.c
>>> b
<__main__.B object at 0x10835c048>
>>> c
<__main__.C object at 0x1085ccac8>
>>> b.c
<__main__.C object at 0x1085ccac8>
>>> c.b
<__main__.B object at 0x10835c048>
>>> b.c.b.c.b
<__main__.B object at 0x10835c048>