当我执行这个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()
输出:
1
{'asf': '----', 'asdf': '===='}
1
{'asf': '----', 'asdf': '===='}
答案 0 :(得分:5)
问题与n
是字典无关;这是n
是一个类属性而不是实例属性。这意味着该类的所有实例共享一个值。
解决方案只是将其转换为实例变量 - 将其分配到方法(通常是__init__
方法)中,而不是在类定义中。
class A(object):
def __init__(self):
self.n = {}
您可能会问为什么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
答案 1 :(得分:0)
n = {}
这不会像其他语言那样做。在其他语言中,您可能希望这声明一个始终使用空dict初始化的实例属性。在Python中,它创建了一个类属性。所有实例共享相同的n
。
要解决此问题,请编写构造函数并在self
上设置属性:
def __init__(self):
self.a = 0
self.n = {}