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?
-
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).jasonharper– jasonharper2021年06月15日 14:02:55 +00:00Commented Jun 15, 2021 at 14:02
-
Can I refer to the already existing variable?YoavKlein– YoavKlein2021年06月15日 14:04:28 +00:00Commented Jun 15, 2021 at 14:04
2 Answers 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.
Comments
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