当我执行这个python代码时,它会生成下面的输出.
class A(object):
a = 0
n = {}
def inc(self):
self.a += 1
def add(self, key, obj):
self.n[key] = obj
def printn(self):
print self.a
print self.n
b = A()
c = A()
b.add("asf", "----")
c.add("asdf", "====")
b.inc()
c.inc()
b.printn()
c.printn()
Run Code Online (Sandbox Code Playgroud)
输出:
1
{'asf': '----', 'asdf': '===='}
1
{'asf': '----', 'asdf': '===='}
Run Code Online (Sandbox Code Playgroud)
这个问题与n作为字典无关; 它n是一个类属性而不是实例属性.这意味着该类的所有实例共享一个值.
解决方案只是将其转换为实例变量 - 将其分配到方法(通常是__init__方法)中而不是在类定义中.
class A(object):
def __init__(self):
self.n = {}
Run Code Online (Sandbox Code Playgroud)
你可能会问为什么同样的事情不会发生a.嗯,确实如此.您正在创建一个共享a,就像使用n.
但是你没有调用a那个改变它的共享上的任何方法(事实上,你不能,因为int它是不可变的;它没有任何改变它的方法).有了n,这self.n[key] = object可能看起来不像是方法调用(实际上是这样self.n.__setitem__(key, object)),但显而易见的是它正在改变n就地的值,这是关键所在.
你只需要分配一个新值self.a.这会创建一个新的实例属性,该属性会隐藏同名的class属性 - 这会让人感到困惑,但它可以按照您的意愿运行.n如果您只想构建一个新值并将其分配给以下内容,则可以获得相同的行为self.n:
def add(self, key, obj):
new_n = copy.copy(n)
new_n[key] = obj
self.n = new_n
Run Code Online (Sandbox Code Playgroud)