0

I know Python does not work with references, unlike Perl and others, but is it possible to create a simple variable whose values are linked, because they reference the same memory address? I know shallow copies of lists and dictionaries contain values that reference the same address.

>>> foo = 1
>>> bar = foo
>>> bar = 0
>>> foo
1
>>> foo = [1,2]
>>> bar = foo
>>> bar[1] = 0
>>> foo
[0,2]

Cf. in Perl

$ref = 1
$foo = \$ref
$bar = $foo
print $$bar //gives 1
$$foo = 0
print $$bar //gives 0

The reason why is that I am curious to how could it be done/hacked in Python. To give a concrete example is that I would have liked to have given a class two "synonymous" attributes. I suppose that one could pull off a shenanigan like this (untested, sorry if wrong) by masking the second value:

class fake:
   def __init__(self,template):
       self.ref = template # keep alive
       self.__dict___ = template.__dict__
       self.__class___ = template.__class__
   def __getitem__(self):
       return self.ref.__getitem__
   def __setitem__(self,value):
       self.ref.__setitem__(value)

But that is not quite in the spirit of what I was curious about, but if a hack is the only way, I'll go for that and would love to know the best way.

Matteo Ferla
  • 2,128
  • 1
  • 16
  • 27
  • In Python you would store the value in some object that you can reference. For instance, you could put it in a list as the sole element, e.g. `[x]`, then use references to the list. Or you could put it in a `dict`, or create a `class` for it. – Tom Karzes Mar 27 '16 at 17:08

3 Answers3

1

You cannot change immutable objects. You can only reassign reference.

foo = bar = 1
bar = 0

Here you doesn't destroy 1 in memory, this is what immutability about, you just reassign bar point to 0.

foo = bar = [1,2] 
bar[1] = 100 

Here you change referenced object in memory.

>>> b = 1
>>> id(b)
15216984
>>> b = 2
>>> id(b)
15216960  # reference points to another object
>>> a = [1,2]
>>> id(a)
139917071841904
>>> a[0] = 100
>>> id(a)
139917071841904 # object is the same, therefore all references pointed to it will show changes  
Rudziankoŭ
  • 10,681
  • 20
  • 92
  • 192
0

Why not just create an @property function that has the second name, but returns the first value?

class C:
    def __init__(self):
        self.attr1 = 12345

    @property
    def synonym(self):
        return self.attr1

    @synonym.setter
    def synonym(self, value):
        self.attr1 = value

This would let references to synonym be passed through to attr1.

aghast
  • 14,785
  • 3
  • 24
  • 56
-1

There is a way to 'hack' it with deepcopy.

from copy import deepcopy
foo = [1,2]
bar = deepcopy(foo)
bar[1] = 0
print bar, foo

Check here for explanation

Alexey Smirnov
  • 2,573
  • 14
  • 20