我做了一些細微的修改你的代碼:
class A:
def __init__(self, name):
self.name = name
self.owner = None
def setChild(self, l):
l.owner = self
def getTopParent(self , depth=0):
if(self.owner == None): # None == top parent
print(' ' * depth + "Got top: %s" % self.name)
print(' ' * depth + "Returning: %s" % self)
return self
else:
print(' ' * depth + "checking %s" % self.name)
tmp = self.owner.getTopParent(depth=depth + 1)
print(' ' * depth + "returned from call while checking %s" % self.name)
print(' ' * depth + "returned value was: %s" % tmp)
a = A("parent")
b = A("child1")
c = A("child2")
d = A("child3")
a.setChild(b)
b.setChild(c)
c.setChild(d)
d_top_parent = d.getTopParent()
print('----------------')
print d_top_parent
現在你可以看到發生了什麼事情,當你調用d.getTopParent()
上。這裏的輸出:
checking child3
checking child2
checking child1
Got top: parent
Returning: <__main__.A instance at 0x0000000002DE8DC8>
returned from call while checking child1
returned value was: <__main__.A instance at 0x0000000002DE8DC8>
returned from call while checking child2
returned value was: None
returned from call while checking child3
returned value was: None
----------------
None
在中間那裏,你可以看到它發現頂級父母並返回它。但return
返回到從[1]調用該函數的地方。所以只返回到「檢查child1」的調用。
早在「檢查child1」調用,它被稱爲self.owner.getTopParent()
,已返回的前母公司。在你的原始版本中,之後沒有更多的代碼,所以執行「結束」功能。在我的版本中,它將從self.owner.getTopParent()
返回的值存儲到變量tmp
中並打印出來,因此我們可以看到它是什麼。但是,它也會從功能的結尾處退出。
在Python中,敲一個函數的結尾相當於return None
,所以這就是返回給「檢查child1」的調用者的內容。因此,「檢查child2」調用獲取從self.owner.getTopParent()
返回的值None
。然後退出該函數的結尾,返回None
給它的調用者。[2]等等。
如果添加return tmp
我的版本,在else
分支印刷後,你會得到這樣的輸出:
checking child3
checking child2
checking child1
Got top: parent
Returning: <__main__.A instance at 0x0000000002E68DC8>
returned from call while checking child1
returned value was: <__main__.A instance at 0x0000000002E68DC8>
returned from call while checking child2
returned value was: <__main__.A instance at 0x0000000002E68DC8>
returned from call while checking child3
returned value was: <__main__.A instance at 0x0000000002E68DC8>
----------------
<__main__.A instance at 0x0000000002E68DC8
現在每個「檢查childN」呼叫來自呼叫self.owner.getTopParent()
接收一個值,並將其給下一個最外面的來電者。
如果你叫什麼,你想它的返回值去任何地方,你必須告訴它去哪裏。這可以用賦值語句將它存儲在某個地方,或者直接作爲參數傳遞給另一個調用,或直接返回它。如果你只是有一個像這樣的線路裸呼叫:
self.owner.getTopParent()
然後返回的值無處可用,不能用於任何目的[3]。
您調用的函數恰好與您所在的函數具有相同的名稱並不相關;遞歸調用和完全一樣,都是非遞歸調用。我總是對很多人感到困惑的遞歸感到驚訝,但這可能只是因爲我不記得再學習它是什麼感覺。 :)
[1]如果你想想看,return
有這樣的工作方式。你如何編寫一個調用其他函數的函數,如果它們返回的返回值一直跳到最外層的調用(如果你在交互式解釋器中運行,那麼它會顯示爲輸出)?
[2]此None
與致電self.owner.getTopParent()
的None
無關。
[3]除非您直接在交互式解釋器中鍵入該值,否則Python將爲您輸出返回值,以便您可以看到它是什麼。它也祕密地將它保存在變量_
中,所以如果你認爲在看到它之後確實需要它,那麼你可以得到它的結果。但從原則上和其他任何環境來看,如果你對任何你所稱的東西的回報價值沒有做任何事情,那麼你就失去了價值。
因爲你沒有在'else'子句中返回任何東西 – JBernardo