0

我有以下两个代码示例

示例 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

有什么解释吗?

4

5 回答 5

2

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

有关详细说明,请参阅此问题: 为什么属性引用在 Python 继承中表现得像这样?

至于你为什么得到None- 该update方法改变了它的 dict ,并返回None.

于 2013-08-14T19:38:21.270 回答
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__,那么instance.__class__.__dict__将被检查。

于 2013-08-14T19:38:37.850 回答
1

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

于 2013-08-14T19:39:48.563 回答
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。

于 2013-08-14T19:44:45.363 回答
0

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

于 2013-08-14T19:37:47.573 回答