python class 对象的可变性何时会影响赋值?

When does mutability of python class objects affect assignments?

我对 python 对 classes/objects 的可变特性的理解是,如果您进行赋值,那么对原始值的任何更改也会更改指定的 variable/object。我对此感到困惑piece of code below

# Recursive solution to Flatten Binary Tree to Linked List by LeetCode

# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    # @param root, a tree node
    # @return root, a tree node
    def flattenHelper(self, root):
        if root == None:
            return None
        else:
            left = root.left
            right = root.right
            root.left = None    # Truncate the left subtree
            current = root

            # Flatten the left subtree
            current.right = self.flattenHelper(left)
            while current.right != None:    current = current.right

            # Flatten the right subtree
            current.right = self.flattenHelper(right)
            return root

    # @param root, a tree node
    # @return nothing, do it in place
    def flatten(self, root):
        self.flattenHelper(root)
        return

问题:执行root.left = None后,为什么变量left不会自动设置为None

Python 中的赋值 始终以相同的方式工作。 它更改 = 符号左侧的内容以引用值右侧的表达式。 完全没有任何问题 "different in the implementation" 如您在评论中所问。

有时左侧的项目是容器(列表、字典、对象)中的槽。这些对象是可变的(可以更改),因此您可以更改它们的插槽所指的内容。当你这样做时,例如:

a = b = [0]

现在 ab 是同一对象的两个不同名称。如果你做 a[0] = 1 那么 b[0] 也变成 1,因为 ab 是同一个对象,并且赋值不会改变这一点,因为你正在分配给插槽 0在 a 引用的对象内;您没有更改 a 本身所指的内容。但是,如果您改为执行 a = [1],则 b[0] 仍为 0,因为 a 现在指向与 b.

不同的列表

这就是您的示例中发生的情况。名称 leftroot.left 最初指的是同一个对象。当您将 root.left 更改为指向不同的对象时,它不会将 left 更改为指向同一对象。为此,left 必须是一个容器,并且必须与 rootnot root.left 是同一个容器,会发生变化的是 left.left,而不是 left 本身。因为除了分配给名称之外,您无法通过任何方式更改名称的值。