Python中obj=None未生效问题解析及root.right置空实现方法
问题分析与解决
代码重现
class Node: def __init__(self,val = 0): self.val = val self.right = None def func(obj,n): if not n: obj = None return obj.right = Node() func(obj.right,0) root = Node() func(root,1) # print(root.right.val) # 输出0而非报错
原因解释
Python的函数参数传递是传对象引用的副本,不是传对象本身:
- 调用
func(root,1)时,函数内的obj是root对象引用的一个副本,此时执行obj.right = Node(),会直接修改root对象的right属性,给它绑定了一个新的Node实例(默认val=0)。 - 接着递归调用
func(obj.right,0),此时obj是刚创建的那个Node实例的引用副本。进入函数后,因为n=0执行obj=None,这只是把函数内部的局部变量obj指向了None,完全不会影响外部root.right已经绑定的那个Node实例,也不会修改root.right这个属性本身。
所以最终root.right依然是之前创建的Node实例,自然能正常输出val=0,不会报错。
修正方案
要实现root.val=0且root.right=None的需求,需要调整函数逻辑,避免不必要的子节点创建,或者直接操作对象的属性而非局部引用:
方案一:按需创建子节点
直接在函数中判断,只有当需要创建子节点时才赋值,否则不操作,保持right为默认的None:
class Node: def __init__(self, val=0): self.val = val self.right = None def func(obj, n): # 仅当n满足条件时才执行子节点创建逻辑,否则直接返回 if n: # 根据需求,此处不需要创建子节点,留空即可 pass root = Node() func(root, 1) print(root.right) # 输出 None print(root.val) # 输出 0
方案二:通过递归返回值控制子节点
让递归函数返回需要绑定的子节点对象,在终止条件返回None,直接赋值给父节点的right:
class Node: def __init__(self, val=0): self.val = val self.right = None def func(obj, n): if not n: # 终止条件:不需要子节点,返回None return None # 创建子节点并递归处理,将递归结果赋值给当前节点的right obj.right = func(Node(), 0) root = Node() func(root, 1) print(root.right) # 输出 None print(root.val) # 输出 0
内容的提问来源于stack exchange,提问作者Trojan
相关产品推荐
相关产品推荐

