我有以下两个代码示例
示例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
)
任何解释?
答案 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
属性。