簡體   English   中英

為什么“返回自我”返回“無”?

[英]Why does 'return self' return None?

我試圖在getTopParent()getTopParent()鏈的頂部節點。 當我打印出self.name ,它的確會打印出父實例的名稱。 但是,當我返回self ,它返回None。 為什么是這樣?

class A:
    def __init__( self, name ):
        self.name = name
        self.owner = None
    def setChild( self, l ):
        l.owner = self
    def getTopParent( self ):
        if( self.owner == None ): # None == top parent
            print( "Got top: %s" % self.name )
            return self
        else:
            print( "checking %s" % self.name )
            self.owner.getTopParent()

a = A( "parent" )
b = A( "child1" )
c = A( "child2" )
d = A( "child3" )
a.setChild( b )
b.setChild( c )
c.setChild( d )

print( d.getTopParent() )
>>> checking child3
    checking child2
    checking child1
    Got top: parent
    None

您需要返回 self.owner.getTopParent()

在Python中,您實際上必須使用return語句從函數中返回某些內容,否則返回None

使用return in

else:
    print( "checking %s" % self.name )
    return self.owner.getTopParent()

因為None是默認的返回值,那么它將輸出:

checking child3
checking child2
checking child1
Got top: parent
<__main__.A instance at 0xb77a628c>

我對您的代碼做了一些小的修改:

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”調用。

回到“檢查self.owner.getTopParent() ”調用中,它稱為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將為您打印返回值,以便您查看返回值。 它還將它秘密地保存在變量_ ,因此,如果您在看完它后仍然確定確實需要它,則可以了解它的含義。 但是原則上以及在任何其他上下文中,如果您對調用的返回值不做任何事情,那么您將失去該值。

ifTrue方面,返回self效果很好。 但是, else端的遞歸調用不會返回任何內容。 使用return self.owner.getTopParent()代替。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM