简体   繁体   中英

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

I had some problem while writing the Join operation on red-black trees. 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? I think that as the a = b line only assign pointers, c.left should now point to 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. So it's actually an identity test.

Secondly we trace back where the two operands c.left and b come from. We find that c.left was assigned the value of a before a was changed to refer to b . Therefore, c.left refers to the node originally bound as a but no longer known under that name.

In C-style pointer language, every variable is actually a pointer (reference), and pointers are always copied by value; 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. Therefore reassigning a only meant there was one less way to find the object it previously referred to. 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).

Ned Batchelder's article on Python Names and Values might clear this up a bit.

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.

a is just a name, not a pointer like in C. You can even do a = 1 , it won't change the RedBlackTreeNode in c.left to int .

c.left has the value of a has it was assigned in a = RedBlackTreeNode() . To change it you need to assign c.left = again.

*In some IDEs you can even see a warning on a = b : Locale variable 'a' value is not used .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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