How to create a reference to a variable in python?

Question:

In the code:

y = 7
x = y
x = 8

Now, y will be 7 and x will be 8. But actually I wan to change y. Can I assign the reference of y and do that?

For example, in C++ the same thing can be achieved as:

int y = 8;
int &x = y;
x = 9;

Now both y & x will be 9

Asked By: viji

||

Answers:

No, Python doesn’t have this feature.

If you had a list (or any other mutable object) you could do what you want by mutating the object that both x and y are bound to:

>>> x = [7]
>>> y = x
>>> y[0] = 8
>>> print x
[8]

See it working online: ideone

Answered By: Mark Byers

You should use a mutable object for this.

In python x & y are just references to objects
so y = 7 means y points to the object 7.
x=y means x too points to 7, but as 7 is immutable so changing the value of x simply changes the object 7 and y still remains pointing to 7.

>>> y = [7]
>>> x = y
>>> x[0] = 8 # here you're changing [7] not x or y, x & y are just references to [7]
>>> y
[8]
Answered By: Ashwini Chaudhary

Alternatively, you could use a self crafted container.

class Value(object):
    def __init__(self, value): self.value = value

y = Value(7)
x = y
x.value = 8
print y.value

ideone

Answered By: glglgl

No, you cannot. As other answer point out, you can (ab?)use aliasing of mutable objects to achieve a similar effect. However, that’s not the same thing as C++ references, and I want to explain what actually happens to avoid any misconceptions.

You see, in C++ (and other languages), a variable (and object fields, and entries in collections, etc.) is a storage location and you write a value (for instance, an integer, an object, or a pointer) to that location. In this model, references are an alias for a storage location (of any kind) – when you assign to a non-reference variable, you copy a value (even if it’s just a pointer, it’s still a value) to the storage location; when you assign to a reference, you copy to a storage location somewhere else. Note that you cannot change a reference itself – once it is bound (and it has to as soon as you create one) all assignments to it alter not the reference but whatever is referred to.

In Python (and other languages), a variable (and object fields, and entries in collections, etc.) is a just a name. Values are somewhere else (e.g. sprinkled all over the heap), and a variable refers (not in the sense of C++ references, more like a pointer minus the pointer arithmetic) to a value. Multiple names can refer to the same value (which is generally a good thing). Python (and other languages) calls whatever is needed to refer to a value a reference, despite being pretty unrelated to things like C++ references and pass-by-reference. Assigning to a variable (or object field, or …) simply makes it refer to another value. The whole model of storage locations does not apply to Python, the programmer never handles storage locations for values. All he stores and shuffles around are Python references, and those are not values in Python, so they cannot be target of other Python references.

All of this is independent of mutability of the value – it’s the same for ints and lists, for instance. You cannot take a variable that refers to either, and overwrite the object it points to. You can only tell the object to modify parts of itself – say, change some reference it contains.

Is this a more restrictive model? Perhaps, but it’s powerful enough most of the time. And when it isn’t you can work around it, either with a custom class like the one given below, or (equivalent, but less obvious) a single-element collection.

class Reference:
    def __init__(self, val):
        self._value = val # just refers to val, no copy

    def get(self):
        return self._value

    def set(self, val):
        self._value = val

That still won’t allow you to alias a “regular” variable or object field, but you can have multiple variables referring to the same Reference object (ditto for the mutable-singleton-collection alternative). You just have to be careful to always use .get()/.set() (or [0]).

Answered By: user395760
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.