views:

128

answers:

6

I want to have a a reference that reads as "whatever variable of name 'x' is pointing to" with ints so that it behaves as:

>>> a = 1
>>> b = 2
>>> c = (a, b)
>>> c
(1, 2)
>>> a = 3
>>> c
(3, 2)

I know I could do something similar with lists by doing:

>>> a = [1]
>>> b = [2]
>>> c = (a, b)
>>> c
([1], [2])
>>> a[0] = 3
>>> c
([3], [2])

but this can be easily lost if one assigns a or b to something instead of their elements.

Is there a simple way to do this?

+4  A: 

No, there isn't a direct way to do this in Python. The reason is that both scalar values (numbers) and tuples are immutable. Once you have established a binding from a name to an immutable value (such as the name c with the tuple (1, 2)), nothing you do except reassigning c can change the value it's bound to.

Note that in your second example, although the tuple is itself immutable, it contains references to mutable values. So it appears as though the tuple changes, but the identity of the tuple remains constant and only the mutable parts are changing.

Greg Hewgill
Indeed the tuple use might be misleading, since I'm after indirect mutability after all. Even though the reference itself should be immutable.
Unode
+2  A: 

Whatever possible solution you come up with the second last line will always destroy it:

a = 3

This will assign a completely new content to the variable. Unless a stands for a property of an object or something (or a key in a list, as you did in your own example), you won't be able to have a relation between the first and last a.

poke
+1 to use of @property although the reference becomes the function call not the actual int.
Unode
+1  A: 

There isn't a way in Python, not only because numbers are immutable, but also because you don't have pointers. Wrapping the value in a list simulates that you have pointers, so that's the best you can do.

Claudiu
A: 

You can try creating your own pointer class and your own pointer storage object to emulate the system's internal stack.

Steven Bluen
i think emulating pointers using the list-wrap is easier
Claudiu
You're entirely correct if you don't mind using an unusual programming style and not being able to do pointer arithmetic.
Steven Bluen
+2  A: 

If you just need the current values to be placed in a tuple on the fly you could use a lambda. You'll have to call c, not just return it or use it, but that may be acceptable in your situation. Something like this:

>>> a = 1
>>> b = 2
>>> c = lambda: (a, b)
>>> c()
(1, 2)
>>> a = 3
>>> c()
(3, 2)
g.d.d.c
+1  A: 
class ByRefValue(object):
    def __init__(self, value):
        self.value = value

Pass it around wherever you like, remembering that you need to access the value member rather than the entire object.


Alternatively, globals().get('a', 0) will return the value of a if it is in the global namespace (or zero if it isn't).


Finally:

import threading
tls = threading.local()

tls.a = 1

If you import tls into every module where you need it, you will access the same value for a on each thread. Depending on how your program is set up, this may be acceptable, ideal or useless.

Zooba