Python函数变量赋值与自定义类

时间:2018-01-01 00:37:52

标签: python immutability

为什么replaceNode1工作但是replaceNode2不工作?我想到了可变性但是None是可变的。谢谢你的时间

class Node:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None

def replaceNode1():
    node = [None]
    def doit(val, node):
        node[0] = Node(val)
    doit(20, node)
    return node[0].val    # return 20

def replaceNode2():
    node = None
    def doit(val, node):
        node = Node(val)
    doit(20, node)
    return node.val      # return 'NoneType' has no attribute 'val'

1 个答案:

答案 0 :(得分:0)

python中的赋值运算符没有按照您的想法执行。我希望这有助于阐明:

假设您使用None创建一个列表对象,因为它是唯一的元素,并使用id获取其内存位置:

>>> node = [None]

>>> id(node)

4397969352

现在你改变它的第一个值:

>>> node[0] = 100

>>> print(node[0])

100

>>> id(node)

4397969352

列表的内存位置未更改(但是它的第一个元素的内存位置有)。当您更改变量名的值时,python会将变量的名称分配给另一个内存位置:

>>> node = None

>>> id(node)

4394834344

>>> node = Node(10)

>>> id(node)

4397990184

如上所示,node现在指向内存中的不同位置。

因此,在您调用函数replaceNode2的代码中,将本地变量 节点分配给新的Node对象,该对象指向新的内存位置,而父范围中的节点仍指向原始内存位置且仍为NoneType对象。这就是你得到那个错误的原因。不是因为NoneType对象的可变性,而是因为python将对象分配给名称以及变量范围的工作方式。