2017-04-26 53 views
0

我有兩個類,B和C.實例化兩個類別之間的相互引用

我想用C引用實例化B,用B引用C。

我可以添加一個setter方法,但不知道如果我能做到這一點的初始化階段或任何其他優雅的方式

+1

你這是什麼意思是*精確地* *它聽起來非常直截了當......但是你絕對不應該在Python中使用getter和setter。 –

+0

'a = A(); b = B(); a.b,b.a = b,a' –

+0

好嗎?在C創建之前,我怎樣才能將C的引用傳遞給B. –

回答

1

這是不可能的內__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代碼行更精細的分辨率。

+0

它也沒有同時傳遞給兩個構造函數的引用,這當然是不可能的。 –

+2

@JoshLee把頭髮分解成荒謬的程度。即使是原子操作也不能同時做兩件事情。 –

+0

@AdamSmith只是爲了澄清。問的具體問題是不可能的,但有各種創造性的方式來回答它。 –

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>