简体   繁体   English

为什么 Python 中的值/指针赋值行为如此?

[英]Why does value/pointer assignment behave like this in Python?

I had some problem while writing the Join operation on red-black trees.在红黑树上编写 Join 操作时遇到了一些问题。 I found what's causing it and tried to simplify it into the following code (because whole blocks of red-black tree code are pretty much unreadable).我找到了导致它的原因并尝试将其简化为以下代码(因为整个红黑树代码块几乎不可读)。

So can anyone explain to me why the final line evaluates to False?那么任何人都可以向我解释为什么最后一行评估为 False 吗? I think that as the a = b line only assign pointers, c.left should now point to b.我认为由于 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

Good old name and value confusion, here with a dash of complicated code.好旧的名称和价值混淆,这里有一些复杂的代码。 Let's work backwards.让我们向后工作。

First, you're comparing using == .首先,您使用==进行比较。 Here those are both objects of type RedBlackTreeNode , which doesn't override the equality behaviour.在这里,它们都是RedBlackTreeNode类型的对象,它们不会覆盖相等行为。 So it's actually an identity test.所以这实际上是一个身份测试。

Secondly we trace back where the two operands c.left and b come from.其次我们追溯两个操作数c.leftb的来源。 We find that c.left was assigned the value of a before a was changed to refer to b .我们发现c.lefta更改为引用b之前被分配了a的值。 Therefore, c.left refers to the node originally bound as a but no longer known under that name.因此, c.left指的是最初绑定为a但不再以该名称为人所知的节点。

In C-style pointer language, every variable is actually a pointer (reference), and pointers are always copied by value;在 C 风格的指针语言中,每个变量实际上都是一个指针(引用),而指针总是按值复制; there is no type for pointer to pointer, so they can't alter each other even though they can point to the same data.指向指针的指针没有类型,因此即使它们可以指向相同的数据,它们也不能相互改变。

Python's objects are entities in their own right, and variables are merely names referring to objects. Python 的对象本身就是实体,而变量只是引用对象的名称。 Therefore reassigning a only meant there was one less way to find the object it previously referred to.因此,重新分配a only 意味着找到之前提到的 object 的方法少了一种。 Each name (whether in your locals, the module's globals or an object like c ) only refers to some object, they know nothing of each other (though there may be reference counts to track their existence).每个名称(无论是在本地,模块的全局变量还是 object 之类的c )仅指一些 object,但它们可能不知道彼此的引用计数。

Ned Batchelder's article on Python Names and Values might clear this up a bit. Ned Batchelder 关于 Python 名称和值的文章可能会澄清这一点。

It's also possible for things to look like these names but redirect to more complex behaviour.也有可能看起来像这些名称但重定向到更复杂的行为。 That's what custom attribute access and properties do, particularly for things that translate like ctypes structures.这就是自定义属性访问属性所做的事情,特别是对于像ctypes结构这样的翻译。

a is just a name, not a pointer like in C. a只是一个名称,而不是 C 中的指针。 You can even do a = 1 , it won't change the RedBlackTreeNode in c.left to int .您甚至可以执行a = 1 ,它不会将c.left中的RedBlackTreeNode更改为int

c.left has the value of a has it was assigned in a = RedBlackTreeNode() . c.left具有a的值,它是在a = RedBlackTreeNode()中分配的。 To change it you need to assign c.left = again.要更改它,您需要再次分配c.left =

*In some IDEs you can even see a warning on a = b : Locale variable 'a' value is not used . *在某些 IDE 中,您甚至可以在a = b上看到警告: Locale variable 'a' value is not used

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM