Reputation: 28716
I have the following Python code:
#!/usr/bin/env python2.6
class container(object):
name = 'container'
configuration = {'var1': 'var1',
'var2': 'var2'}
if __name__ == "__main__":
container1 = container()
container2 = container()
container2.name = 'container2'
container2.configuration['var2'] = 'newvar2'
print container1.name
print container1.configuration['var2']
I expect this to print 'container' and 'var2', but for the latter it prints 'newvar2' instead
Why does the configuration variable point to the same dictionary for both objects? How can I fix this?
Most answers are already explaining that name and configuration are class variables. Why does the change of container2.name not influence container1.name?
Upvotes: 1
Views: 100
Reputation: 71014
Because configuration
is a class variable and not an instance variable. Fixing this should fix your problem.
class container(object):
def __init__(self):
self.name = 'container'
self.configuration = {'var1': 'var1',
'var2': 'var2'}
What's going on here is that configuration
ends up living in containter.__dict__
instead of in the dictionaries of its instances when you make it a class variable. This means that c.configuration
is just accessing container.__dict__['configuration']
for all instances c
.
For any class variable, an assignment of the form c.foo = x
, creates an entry for foo
in c.__dict__
which shadows its entry in container.__dict__
. So a lookup will return that first. If you delete it, then a lookup will go back to retrieving the class instance. You could do
c = container()
c.configuration = x
and then c.configuration
would be whatever x
was. But inserting a key isn't an assignment, it's a method call on an existing object accessed through an existing binding.
You could get away with making name
a class variable but if you want it to change from one instance to another then it should be an instance variable (unless you want a class wide default of course).
so:
=
, setattr
or directly inserting in __dict__
) on an instance will shadow a class variable. The class variable is still there.Upvotes: 3
Reputation: 28693
Because name
and configuration
are class or static members of the container class and they are shared for all the instances of container. Use self.name, self.configuration for instance variables:
class container(object):
def __init__(self):
self.name = "container"
self.configuration = {}
Upvotes: 3
Reputation: 45295
self.name = 'container'
self.configuration = {'var1': 'var1',
'var2': 'var2'}
In init() if they are the class variables.
Upvotes: 0