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]
现在 a
和 b
是同一对象的两个不同名称。如果你做 a[0] = 1
那么 b[0]
也变成 1,因为 a
和 b
是同一个对象,并且赋值不会改变这一点,因为你正在分配给插槽 0在 a
引用的对象内;您没有更改 a
本身所指的内容。但是,如果您改为执行 a = [1]
,则 b[0]
仍为 0,因为 a
现在指向与 b
.
不同的列表
这就是您的示例中发生的情况。名称 left
和 root.left
最初指的是同一个对象。当您将 root.left
更改为指向不同的对象时,它不会将 left
更改为指向同一对象。为此,left
必须是一个容器,并且必须与 root
、not root.left
是同一个容器,会发生变化的是 left.left
,而不是 left
本身。因为除了分配给名称之外,您无法通过任何方式更改名称的值。
我对 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]
现在 a
和 b
是同一对象的两个不同名称。如果你做 a[0] = 1
那么 b[0]
也变成 1,因为 a
和 b
是同一个对象,并且赋值不会改变这一点,因为你正在分配给插槽 0在 a
引用的对象内;您没有更改 a
本身所指的内容。但是,如果您改为执行 a = [1]
,则 b[0]
仍为 0,因为 a
现在指向与 b
.
这就是您的示例中发生的情况。名称 left
和 root.left
最初指的是同一个对象。当您将 root.left
更改为指向不同的对象时,它不会将 left
更改为指向同一对象。为此,left
必须是一个容器,并且必须与 root
、not root.left
是同一个容器,会发生变化的是 left.left
,而不是 left
本身。因为除了分配给名称之外,您无法通过任何方式更改名称的值。