Reputation: 2705
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?
Upvotes: 0
Views: 45
Reputation: 92440
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
Upvotes: 1
Reputation: 124
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.
Upvotes: 2