The problem has nothing to do with n
being a dictionary; it's that n
is a class attribute instead of an instance attribute. That means all instances of the class share a single value.
The solution is simply to turn it into an instance variable—assign it inside a method (usually the __init__
method) instead of inside the class definition.
class A(object):
def __init__(self):
self.n = {}
You may ask why the same thing doesn't happen with a
. Well, it does. You're creating a single shared a
, just as with n
.
But you're not calling any methods on that shared a
that change it (in fact, you can't, because int
is immutable; it doesn't have any methods that change it). With n
, that self.n[key] = object
may not look like an method call (it's actually self.n.__setitem__(key, object)
), but it's obvious that it's changing the value of n
in-place, which is the key here.
You're just assigning a new value to self.a
. That creates a new instance attribute that shadows the class attribute of the same name—which is confusing, but it works as you want it to. You could get the same behavior with n
if you wanted just by building a new value and assigning it to self.n
:
def add(self, key, obj):
new_n = copy.copy(n)
new_n[key] = obj
self.n = new_n