Python:类和实例变量的行为
我有以下两个代码示例 例1:Python:类和实例变量的行为,python,instance-variables,class-variables,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(obj
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
我对上述行为感到十分惊讶
为什么仅通过添加_dict={}就可以成功编译示例2
行,以及类范围中存在的行。
为什么None
输出?
我认为类范围变量和实例变量没有关系
(专用于self
)
任何解释?
self.\u dict
尚不存在,因此第一个版本引发了该异常。第二种方法实际上是在实例上查找\u dict
而不是更新class属性,然后将类级字典分配给实例范围\u dict
属性。self.\u dict
尚不存在,因此第一个版本引发该异常。第二种方法实际上是在实例上查找\u dict
而不是更新class属性,然后将类级字典分配给实例范围\u dict
属性。您的“示例2”在类级定义了一个字典。该类的所有实例都将共享同一个字典,至少除非您在该实例上重新分配_dict
有关详细说明,请参见此问题:
至于为什么会得到
None
,update
方法会更改其dict,并返回None
,您的“示例2”在类级别定义了一个字典。该类的所有实例都将共享同一个字典,至少除非您在该实例上重新分配_dict
有关详细说明,请参见此问题:
至于为什么会得到
None
,update
方法会更改其dict,并返回None
,None
输出是因为dict.update
返回None。它修改字典本身,但不返回任何内容。所以您可能想要self.\u dict.update({key:value})
。但是,self.\u dict
在初始化时不存在。所以做self会更有意义。_dict={key:value}
。如果您试图修改对象的内部字典,那么应该执行self.\uu dict\uuu.update({key:value})
。然而,这是不好的做法。更好的方法是编写setattr(self、key、value)
。示例2成功运行的原因是,如果您尝试执行getattr(实例,事物)
(这是instance.thing
所做的),而thing
不在实例中,然后,实例.\uuuuuu类\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
输出是因为dict.update
返回无。它修改字典本身,但不返回任何内容。所以您可能想要self.\u dict.update({key:value})
。但是,self.\u dict
在初始化时不存在。所以做self会更有意义。_dict={key:value}
。如果您试图修改对象的内部字典,那么应该执行self.\uu dict\uuu.update({key:value})
。然而,这是不好的做法。更好的方法是编写setattr(self、key、value)
。示例2成功运行的原因是,如果您尝试执行getattr(实例,事物)
(这是instance.thing
所做的),而thing
不在实例中,然后检查instance.\uuuu class\uuuuu.\uuuu dict\uuuuu
。因为示例2中的\udict
是一个类变量,所以它是MyClass
的一个属性,而示例1中的u dict是一个实例变量,所以它是一个实例属性。因为示例2中的\udict
是一个类变量,所以它是MyClass
的一个属性,其中示例1中的_dict是一个实例变量,因此它是一个实例属性。示例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仍然为空,并且未返回任何值。示例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仍然为空,并且不返回任何值