Are aliases guaranteed to refer to the same object in Python?

The Python docs mention the following names, which are aliases for objects:

Objects have personality, and multiple names (in multiple scopes) can be bound to the same object. This is called a pseudonym in other languages. This is usually not appreciated at first glance in Python and can be safely ignored when dealing with immutable base types (numbers, strings, tuples). However, aliasing has perhaps a surprising effect on the semantics of Python code, which includes mutable objects such as lists, dictionaries, and most other types. This is usually used in the best interest of the program, as in some respects aliases behave like pointers. For example, passing an object is cheap because implementation is done only by a pointer; and if the function modifies the object passed as an argument,the caller sees this change - this removes the need for two different argument passing mechanisms as in Pascal.

In some other high-level languages, it is common for primitive types to be special and copied instead of reference, for performance reasons. For example, in Java:

int a = 20000;
int b = a;

      

The above code will copy the value 20000

instead of a pointer to value 20000

. In this case, a

and b

will probably occupy different places in memory. Because of the special wrapping on ==

to check for equality instead of identity only for primitive types, I don't believe this behavior can be checked in normal code.

On the other hand, limited testing with such types as int

and str

in Python 3 shows that actually pointers are copied and not the values as specified in the documentation:

a = 20000
b = a
a is b # True

      

This is a very nice property that makes the language very consistent, since there is no special wrapper for primitive types. All assignments reassign the name to another object. However, for performance reasons, is it possible for the Python interpreter to type special cases like int

?

Hence my question is, is this property guaranteed for primitive types? In other words, is it always true that there will be a b = a

comparison after , regardless of the Python interpreter used?a is b

True

+3


source to share


4 answers


Yes, it is stated in the documentation :

If the target is id (name):

If the name does not appear in the global expression in the current code block: the name is bound to an object in the current local namespace.

Otherwise: the name is bound to an object in the current global namespace.



(There is an additional case related to Python 3 nonlocal

, but the rule is the same, the only difference is which namespace occurs in.)

Note that this only applies when assigning a naked name . If the assignment is something like a.foo = b

or a[blah] = b

, all bets are off and something can happen.

+3


source


b = a

make names b

and a

references to the same object. So yes, it a is b

will always be True in Python .



+4


source


>>> int
<class 'int'>

      

Python doesn't use primitive types the same way Java does. As you can see here int

is a class. Instances of this class are objects with all of this. It just so happens that this is a built-in class and not defined in a file .py

somewhere.

Think about Java Integer

vs behavior int

.

When you execute a = 1; b = a

, you are setting a b

reference to the same object that is being referenced a

, so it does not copy the value.

As far as the custom wrapper goes, CPython makes "small" integers (-5 to 255) single, so they don't need to be recreated, but that's an implementation detail.

+2


source


All variables and expressions in Python are references (semantically equivalent to pointers to objects). If you are familiar with C ++, it looks like this:

object *a = new object(20000);
object *b = a;
a == b // true

      

Assigning one variable to another will copy the value, the pointer. Once assigned, the two pointers will always point to the same object.

0


source







All Articles