为什么“返回自我”不返回任何内容?

2024-10-01 13:38:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在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

Tags: nameselfnonetopdefparentprintowner
3条回答

在中使用return

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

由于None是默认返回值,因此它将输出:

^{pr2}$

我对你的代码做了一些小小的修改:

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()时发生了什么。输出如下:

^{pr2}$

在中间你可以看到它找到了顶级父级并返回了它。但是return返回到从[1]调用此函数的位置。因此只返回到“checking child1”调用。在

回到“checking child1”调用中,它被称为self.owner.getTopParent(),它返回了顶级父级。在您的原始版本中,此后没有更多的代码,因此函数的执行“停止”。在我的版本中,它将从self.owner.getTopParent()返回的值存储到一个变量tmp中并打印它,这样我们就可以看到它是什么了。但它也会从函数的末尾脱落。在

在Python中,命中函数的结尾相当于return None,因此返回给“checking child1”的调用者。因此,“checking 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

现在,每个“checking childN”调用都从调用self.owner.getTopParent()接收一个值,并将其返回给下一个最外层的调用方。在

如果你调用某个东西,并且你想让它的返回值去任何地方,你必须告诉它去哪里。可以使用赋值语句将其存储在某个地方,或者直接将其作为参数传递给另一个调用,或者直接返回它。如果你只有一个像这样的电话:

self.owner.getTopParent()

然后返回的值就不存在了,不能用于任何目的[3]。在

你正在调用的函数恰好与你所在的函数同名这一事实是不相干的;递归调用的工作原理与非递归调用的工作方式完全相同。我总是惊讶于递归对于很多人来说是多么令人困惑,但这可能只是因为我不记得再学习它是什么感觉了。:)


[1]如果你仔细想想,return这样做。如果其他函数返回时返回值一直跳到最外层的调用(如果在交互式解释器中运行,则显示为输出),那么如何编写一个调用其他函数的函数?在

[2]这个None与从对self.owner.getTopParent()的调用接收{}无关。在

[3]除非您直接在交互式解释器中键入该值,否则Python会为您打印返回值,这样您就可以看到它是什么了。它还秘密地将它保存在变量_中,因此如果您在看到它之后决定确实需要它,那么您可以得到它的原样。但原则上,在任何其他上下文中,如果你对你调用的东西的返回值不做任何操作,那么你就失去了这个值。在

你需要返回self.owner.getTopParent()!在

在Python中,必须实际使用return语句从函数中返回某些内容,否则返回None。在

相关问题 更多 >