3
first = 30
second = first
first = 20
print("first: ", first, "second: ", second)
# first:  20 second:  30

In the above example, it seems the variable second points directly to the memory address for 30, and when first is reassigned it therefore has no effect on second.

class Circle: 
    pi = 3.1419

circle1 = Circle()
circle2 = Circle()
circle2.pi = 10
print(Circle.pi, circle1.pi, circle2.pi)
# 3.1419 3.1419 10

Circle.pi = 40
print(Circle.pi, circle1.pi, circle2.pi)
# 40 40 10

In the above example however, when I assign 40 to Circle.pi, it has an affect on circle1.pi because circle1.pi was pointing to Circle.pi instead of the memory address for 3.1419.

ScottyBlades
  • 12,189
  • 5
  • 77
  • 85
  • 4
    Python's language semantics are not defined in terms of pointers. Pointers are involved in the implementation, but you should not think of variables as pointers. – user2357112 Apr 22 '20 at 01:20
  • 1
    You especially shouldn't think of attributes as pointers, because attribute access has way too many fallbacks and customization hooks for that. – user2357112 Apr 22 '20 at 01:30
  • Just edited. Is that better? – ScottyBlades Apr 22 '20 at 01:33
  • 1
    A quibble: `circle1.pi` doesn't point to `Circle.pi`, it **is** `Circle.pi`. As written, `circle1` has no attribute `pi`, so when you attempt to access `circle1.pi`, the lookup defers to the class object. If you write e.g. `circle1.pi = 7` you will add an attribute to `circle1`, but you will not mutate `Circle` itself. – Brian61354270 Apr 22 '20 at 01:40
  • So `circle1.pi` is `Circle.pi` except when `circle1.pi` is reassigned, it doesn't reassign `Circle.pi` so how can they both be one and the same? It seems they return the same result initially but otherwise they are not one and the same. – ScottyBlades Apr 22 '20 at 01:46
  • 1
    @ScottyBlades They are "one in the same" in the sense that writing `circle1.pi` when `circle1` has no attribute `pi` (i.e. `circle1.__dict__` doesn't contain an entry for `pi`) is translated to a lookup on the class object (i.e. `Circle.pi`). Essentially, writing `circle1.pi` results in `circle1.__dict__` being checked, and if that fails, `circle1.__class__.__dict__` is checked. If neither contain `pi`, an `AttributeError` is raised. – Brian61354270 Apr 22 '20 at 02:02
  • Does this answer your question? [How does Python referencing work?](https://stackoverflow.com/questions/9724802/how-does-python-referencing-work) – kaya3 Apr 22 '20 at 02:24

2 Answers2

3

Python's semantics in this area can be surprising to people coming from languages with explicit pointers, but the rules are not complicated.

I highly recommend reading Ned Batchelder's Python Names and Values.

In short, Python associates names with values. An immutable value (like the integer in your first example) can't be changed, so multiple names pointing to it can't affect each other. However:

If a mutable value has more than one name, and the value changes, then all names see the change.

That's what you see in your class-based example. It can also be seen with lists:

>>> nums = [1, 2, 3]
>>> a = nums
>>> b = nums
>>> a.append(4)
>>> print(b)
[1, 2, 3, 4]
Paul Bissex
  • 1,611
  • 1
  • 17
  • 22
0

EDITED:
From your class example:

  1. pi is a class attribute of Circle class.
  2. class attributes can be access from the object as you did circle2.pi
  3. However, class attribute, pi is not being modified from your code, circle2.pi = 10, it CREATES an instance attribute with the same name, pi as the class attribute.
ywbaek
  • 2,971
  • 3
  • 9
  • 28
  • **Theres NO NEED to _SHOUT_**. Also, it's a little misleading to say that "class attribute cannot be modified from the object". The type object for any given object can always be accessed (and mutated) from `circle1.__class__`. Likewise, if properties, metaclasses, or other niceties are at play, `circle1.pi = 40` could very well mutate the class object itself. I realize these are pedantic points, but especially for questions such as this, its worth being precise. – Brian61354270 Apr 22 '20 at 01:49
  • @Brian I agree that the phrase can be misleading. Anyhow, none of those thing you mentioned are at play at OP's example. I don't know why you would get offended for bold italic styles, but if you did, I apologize. I'll remove those. – ywbaek Apr 22 '20 at 01:54