[英]Why does value/pointer assignment behave like this in Python?
在红黑树上编写 Join 操作时遇到了一些问题。 我找到了导致它的原因并尝试将其简化为以下代码(因为整个红黑树代码块几乎不可读)。
那么任何人都可以向我解释为什么最后一行评估为 False 吗? 我认为由于 a = b 行只分配指针,c.left 现在应该指向 b。
class RedBlackTreeNode:
def __init__(self, key, color):
self.key, self.color, self.left, self.right, self.parent = key, color, None, None, None
a = RedBlackTreeNode(None, False)
b = RedBlackTreeNode(None, False)
c = RedBlackTreeNode(1, False)
c.left = a
a = b
print(c.left == b)
>>> False
好旧的名称和价值混淆,这里有一些复杂的代码。 让我们向后工作。
首先,您使用==
进行比较。 在这里,它们都是RedBlackTreeNode
类型的对象,它们不会覆盖相等行为。 所以这实际上是一个身份测试。
其次我们追溯两个操作数c.left
和b
的来源。 我们发现c.left
在a
更改为引用b
之前被分配了a
的值。 因此, c.left
指的是最初绑定为a
但不再以该名称为人所知的节点。
在 C 风格的指针语言中,每个变量实际上都是一个指针(引用),而指针总是按值复制; 指向指针的指针没有类型,因此即使它们可以指向相同的数据,它们也不能相互改变。
Python 的对象本身就是实体,而变量只是引用对象的名称。 因此,重新分配a
only 意味着找到之前提到的 object 的方法少了一种。 每个名称(无论是在本地,模块的全局变量还是 object 之类的c
)仅指一些 object,但它们可能不知道彼此的引用计数。
Ned Batchelder 关于 Python 名称和值的文章可能会澄清这一点。
也有可能看起来像这些名称但重定向到更复杂的行为。 这就是自定义属性访问和属性所做的事情,特别是对于像ctypes
结构这样的翻译。
a
只是一个名称,而不是 C 中的指针。 您甚至可以执行a = 1
,它不会将c.left
中的RedBlackTreeNode
更改为int
。
c.left
具有a
的值,它是在a = RedBlackTreeNode()
中分配的。 要更改它,您需要再次分配c.left =
。
*在某些 IDE 中,您甚至可以在a = b
上看到警告: Locale variable 'a' value is not used
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.