Python:类和实例变量的行为

时间:2013-08-14 19:33:22

标签: python instance-variables class-variables

我有以下两个代码示例

示例1:

class MyClass(object):

    def __init__(self, key, value):
         self._dict = self._dict.update({key:value})

m = MyClass('ten',10)
print m._dict

输出:

AttributeError: 'MyClass' object has no attribute '_dict'

例2:

class MyClass(object):
    _dict = {}
    def __init__(self, key, value):
        self._dict = self._dict.update({key:value})

m = MyClass('ten',10)
print m._dict

输出:      None

我对上述行为感到非常惊讶

为什么example2通过添加_dict = {}成功编译 行和类在范围内的行。 还有None输出的原因? 我认为类范围变量与实例变量没有关系 (特别是self

任何解释?

5 个答案:

答案 0 :(得分:2)

您的“示例2”在类级别定义了一个字典。该类的所有实例将共享同一个字典,至少除非您在实例上重新分配_dict。

有关详细说明,请参阅此问题: Why do attribute references act like this with Python inheritance?

至于您获得None的原因 - update方法更改了其dict,并返回None

答案 1 :(得分:1)

None输出是因为dict.update返回None。它修改字典本身,但不返回任何内容。所以你可能想要self._dict.update({key:value})。但是,初始化时不存在self._dict。这样做self._dict = {key: value}会更有意义。如果您尝试修改对象的内部字典,那么您应该self.__dict__.update({key:value})。但是,这是不好的做法。更好的想法是写setattr(self, key, value)。 Example2成功运作的原因是因为如果您尝试执行getattr(instance, thing)instance.thing执行的操作),而thing不在instance.__dict__中,那么{{1}将被检查。

答案 2 :(得分:1)

因为示例2中的_dict是一个类变量,所以它是MyClass的属性,因为示例1中的_dict是一个实例变量,所以它是一个实例属性。

答案 3 :(得分:1)

示例1:您正在尝试更新尚未创建的对象。因此错误。

示例2:在函数的内部作用域中工作时,如果修改变量,则会对先前定义的_dict进行更改。但是如果你赋值,它会在内部范围内创建一个具有相同名称的新变量。

这样可行。

class MyClass(object):
    _dict = {}
    def __init__(self, key, value):
        self._dict.update({key:value})

这不会。

class MyClass(object):
    _dict = {}
    def __init__(self, key, value):
        self._dict = self._dict.update({key:value})

因为您正在进行分配操作。它创造了一个新变量。因此,不会对外部范围中的_dict进行任何更改。外部作用域中的_dict仍然为空,并返回None。

答案 4 :(得分:0)

self._dict尚不存在,因此第一个版本引发了该异常。第二个实际上是通过在实例上查找_dict而改为class属性,然后将类级别字典分配给实例范围_dict属性。