4

I am breaking my old question to parts because it is very messy beast here. This question is related to this answer and this answer. I try to understand pointers, not sure even whether they exist in Python.

# Won't change x with y=4
>>> x = 0; y = x; y = 4; x
0

# Won't change y
>>> x = 0; y = x; x = 2; y
0

#so how can I change pointers? Do they even exist in Python?
x = 0
y.pointerDestination = x.pointerDestination   #How? By which command?
x = 2
# y should be 0, how?

[Update 2: Solved]

Perhaps, contradictive statements about the existence There are no pointers in Python. and Python does not have the concept of a "pointer" to a simple scalar value.. Does the last one infer that there are pointers to something else, nullifying the first statement?

Community
  • 1
  • 1
hhh
  • 50,788
  • 62
  • 179
  • 282
  • Greg Hewgill's answer below is correct, but in another sense, Python variables act as references, which serve some of the same purpose as C pointers. – Russell Borogove Feb 14 '11 at 19:10
  • The second code example in update 1 breaks because `[x] = ...` (as well as `(x,) = ...` (singleton tuple)) is iterable unpacking, which of course expects an iterable on the right hand side (in particular, it expects an iterable that yields one item to be store in `x`). That's wholly unrelated to references, pointers or whatever. –  Feb 14 '11 at 19:53
  • @delnan: thank you, cleared it up and now an open update related to Greg's answer. – hhh Feb 14 '11 at 20:10
  • @delnan: it was based on wrong observation, I had mistake on it and I made a question based on it. It had no value at all, sorry, now much cleaner. – hhh Feb 14 '11 at 20:34

3 Answers3

6

Scalar objects in Python are immutable. If you use a non-scalar object, such as a list, you can do this:

>>> x = [0]
>>> y = x
>>> y[0] = 4
>>> y
[4]
>>> x
[4]
>>> x is y
True

Python does not have the concept of a "pointer" to a simple scalar value.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
2

Don't confuse pointers to references. They are not the same thing. A pointer is simply an address to an object. You don't really have access to the address of an object in python, only references to them.

When you assign an object to a variable, you are assigning a reference to some object to the variable.

x = 0
# x is a reference to an object `0`
y = [0]
# y is a reference to an object `[0]`

Some objects in python are mutable, meaning you can change properties of the object. Others are immutable, meaning you cannot change the properties of the object.

int (a scalar object) is immutable. There isn't a property of an int that you could change (aka mutating).

# suppose ints had a `value` property which stores the value
x.value = 20 # does not work

list (a non-scalar object) on the other hand is mutable. You can change individual elements of the list to refer to something else.

y[0] = 20 # changes the 0th element of the list to `20`

In the examples you've shown:

>>> x = [0]
>>> y = [x]

you're not dealing with pointers, you're dealing with references to lists with certain values. x is a list that contains a single integer 0. y is a list that contains a reference to whatever x refers to (in this case, the list [0]).

You can change the contents of x like so:

>>> print(x)
[0]
>>> x[0] = 2
>>> print(x)
[2]

You can change the contents of the list referenced by x through y's reference:

>>> print(x)
[2]
>>> print(y)
[[2]]
>>> y[0][0] = 5
>>> print(x)
[5]
>>> print(y)
[[5]]

You can change the contents of y to reference something else:

>>> print(y)
[[5]]
>>> y[0] = 12345
>>> print(x)
[5]
>>> print(y)
[12345]

It's basically the same semantics of a language such as Java or C#. You don't use pointers to objects directly (though you do indirectly since the implementations use pointers behind the scenes), but references to objects.

Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
1

There are no pointers in Python. There are things called references (which, like C++ references, happen to be commonly implemented in pointers - but unlike C++ references don't imply pass-by-reference). Every variable stores a reference to an object allocated somewhere else (on the heap). Every collection stores references to objects allocated somewhere else. Every member of an object stores a reference to an object allocated somewhere else.

The simple expression x evaluates to the reference stored in x - whoever uses it has no way to determine that is came from a variable. There's no way to get a link to a variable (as opposed to the contents of it) that could be used to track changes of that variable. Item (x[y] = ...) and member (x.y = ...) assignments are different in one regard: They invoke methods and mutate existing objects instead of overwriting a local variable. This difference is mainly important when dealing with scoping, but you can use either of those to emulate mutability for immutable types (as shown by @Greg Hewgill) and to share state changes across function boundaries (def f(x): x = 0 doesn't change anything, but def g(x): x.x = 0 does). It's not fully up to emulating pass by reference though - unless you replace every variable by a wrapper object whose sole purpose is to hold a mutable val property. This would be the equivalent to emulating pass-by-reference through pointers in C, but much more cumbersome.

  • please, read **[Update 2]**, are yours and Greg's answers contradictive? – hhh Feb 14 '11 at 19:46
  • 1
    @hhh: Not quite. Greg is seemingly confusing pointers with mutability (perhaps because got the question wrong - perhaps because you ask for pointers but really want pass-by-reference semantics?), but he is right that `Python does not have the concept of a "pointer" to a simple scalar value` because Python doesn't have pointers at all. –  Feb 14 '11 at 19:50
  • I wasn't intending to confuse pointers with mutability. Python "variables" are actually always references. However, this is only exposed to the programmer when it's a reference to a mutable object. A reference to a scalar, since scalars are immutable, is indistinguishable from the variable itself containing the actual scalar value. (With [an exception related to the `is` operator](http://stackoverflow.com/questions/306313).) A "pointer to a scalar" would imply that the scalar is mutable, so by considering scalar values immutable, one realises that there cannot be "pointers to" them. – Greg Hewgill Feb 14 '11 at 21:04