0

The docs give the following example:

class Dog:
    tricks = []             # mistaken use of a class variable
    def __init__(self, name):
        self.name = name
    def add_trick(self, trick):
        self.tricks.append(trick)

d1 = Dog('Fiddo')
d2 = Dog('Buddy')

d1.add_trick("role over")
d2.add_trick("play dead")

print(d2.tricks)
["role over", "play dead"]

This demonstrate a bad usage of class variables, since we obviously don't want the same list of tricks for all our dogs.

But when I try this:

class A:
    static_attr = 'Static'
    def __init__(self):
        self.object_attr = 'Objective'
    
    def change_static(self, val):
        self.static_attr = val
        
a1, a2 = A(), A()
a1.change_static("Something")
print(a2.static_attr)

I get:

Static

Why could be the reason that for a list object, when modifying the class variable through an object it is modified for all instances, but with a string it doesnt?

2
  • The difference is that in one case, you modified an existing object (thus it remains a class attribute), and in the other case, you assigned a new value (causing it to become an instance attribute). Commented Jun 15, 2021 at 14:02
  • Can I refer to the already existing variable? Commented Jun 15, 2021 at 14:04

2 Answers 2

2

Here is something to understand it a little better :

class A:
    static_attr = 'Static'
    def __init__(self):
        self.object_attr = 'Objective'
    
    @staticmethod
    def change_static(val):
        A.static_attr = val
        
a1, a2 = A(), A()
A.change_static("Something")
print(a2.static_attr)

A static attribute is common to every instance of the same class. Hence calling this parameter through the object and not the class may be the problem.

Sign up to request clarification or add additional context in comments.

Comments

1

In the first case you tried to access a variable named self.tricks. Python couldn't find that on the instance to it looked for it on the class and found it. Then you manipulated the value that variable points to by appending to the list.

In the second example you create a name called self.static_attr on the instance with self.static_attr = val and assigned a value to it. Now you have two static_attr variables -- one on the class and one on the instance. This is called shadowing.

Now when you try to access self.static_attr and instance that has not defined it on the instance will get the class variable, but instances that have defined it, will get the instance variable. This is described pretty well in the Classes Documentation

Note, you can still refer to the class variable explicitly with something like:

self.__class__.static_attr

or

A.static_attr

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.