Python使用字典时行为怪异

2024-09-27 17:42:30 发布

您现在位置:Python中文网/ 问答频道 /正文

当我执行这个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': '===='}

Tags: key代码selfaddobjobjectdefclass
2条回答

问题与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属性进行阴影处理,这很容易混淆,但它可以按照您的要求工作。如果您只需要构建一个新值并将其赋给self.n,就可以获得与n相同的行为:

def add(self, key, obj):
    new_n = copy.copy(n)
    new_n[key] = obj
    self.n = new_n
n = {}

这在其他语言中做不到。在其他语言中,您可能希望它声明一个实例属性,该属性总是用空dict初始化的。在Python中,它创建一个class属性。所有实例共享相同的n。你知道吗

要修复它,请编写构造函数并在self上设置属性:

def __init__(self):
    self.a = 0
    self.n = {}

相关问题 更多 >

    热门问题