我正试图在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
答案 0 :(得分:7)
您需要返回 self.owner.getTopParent()
!
在Python中,您必须实际使用return
语句从函数返回一些内容,否则返回None
。
答案 1 :(得分:3)
在
中使用return
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>
答案 2 :(得分:2)
我对您的代码稍作修改:
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
,因此返回给“check child1”的调用者。因此,“检查child2”调用将获得从None
返回的值self.owner.getTopParent()
。然后放弃函数的结尾,将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
现在,每个“check childN”调用都会通过调用self.owner.getTopParent()
接收一个值并将其返回到下一个最外面的调用者。
如果你打电话给某个东西,并且你想要它的返回值去任何地方,你必须告诉它去哪里。这可以使用赋值语句将其存储在某处,或者将其作为参数直接传递给另一个调用,或者直接返回它。如果您只是像这一行那样打电话:
self.owner.getTopParent()
然后返回的值无处可去,不能用于任何目的[3]。
您正在调用的函数恰好与您所使用的函数具有相同的名称这一事实无关紧要;递归调用与每个单向的非递归调用完全相同。我总是对许多人的混乱递归感到惊讶,但这可能只是因为我不记得再学习它是什么感觉了。 :)
[1]如果你仔细想想,return
有以这种方式工作。你怎么能编写一个调用其他函数的函数,如果它们返回时返回值一直跳到最外面的调用(并且如果你在交互式解释器中运行则显示为输出)?
[2]此None
与从None
的通话中接收self.owner.getTopParent()
无关。
[3]除非您直接在交互式解释器中输入,否则Python会为您打印返回值,以便您可以看到它是什么。它还秘密地将其保存在变量_
中,因此如果您确定在看到之后确实需要它,那么您可以了解它。但原则上,在任何其他情况下,如果你不对你所称的东西的返回值做任何事情,那么你就会失去价值。
答案 3 :(得分:1)
返回self
在True
的{{1}}方面工作得很好。但是,if
方的递归调用不会返回任何内容。请改用else
。