0
class Circle:
    a = 2
    b = a

#print class variables 
print(Circle.a)
print(Circle.b)

2
2

# updating class variable a to value 100
Circle.a = 100

# printing updated class variables
print(Circle.a)
print(Circle.b)

100
2

Why isn`t class variable b also updating to 100 ? Can I change the variable without a setter method ?

4
  • It's because integers are immutable, immutable variables aren't passed by reference, whereas mutable objects are, such as list or dict. Set a to a list and then append to b to see that they are now 'linked'. Commented Nov 14, 2020 at 11:05
  • @Mandera it's a common misconception that assignment has anything to do with mutability. Assignment works the same way for mutable and immutable objects. The explanation here simply is that initially, the names a and b both point to the same value (2) in memory (assignment never copies data). Then, a is reassigned to point to the value 100. Names are reassigned independently. You would observe exactly the same behavior for a list or dict. Commented Nov 14, 2020 at 11:08
  • 1
    @timgeb Ah that makes sense, thanks for enlightening me! Commented Nov 14, 2020 at 11:09
  • 2
    @Mandera no problem, here's a video by Ned that explains the problem better than I ever could in a comment. Commented Nov 14, 2020 at 11:10

2 Answers 2

1

The names a and b both point to the same value (2) in memory (assignment never copies data). Then, a is reassigned to point to the value 100. Names are reassigned independently.

You did this:

a = 2
b = a

a ----> 2
        ^
       / 
b ----/

a = 100

a ----> 100
b ----> 2
Sign up to request clarification or add additional context in comments.

Comments

1

This would be a good place for a @property decorator to make b point to a. Those however do not work on classmethods. I found https://stackoverflow.com/a/13624858/3936044 to create a nice little @classproperty decorator for us. Applying that to your code would look like this:

class classproperty:
    def __init__(self, fget):
        self.fget = fget

    def __get__(self, owner_self, owner_cls):
        return self.fget(owner_cls)

class Circle:
    a = 2

    @classproperty
    def b(cls):
        return cls.a

#print class variables
print(Circle.a)
print(Circle.b)

2
2

# updating class variable a to value 100
Circle.a = 100

# printing updated class variables
print(Circle.a)
print(Circle.b)

100
100

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.