[英]Python : Behavior of class and instance variables
I have following two code samples 我有以下两个代码示例
Example 1: 范例1:
class MyClass(object):
def __init__(self, key, value):
self._dict = self._dict.update({key:value})
m = MyClass('ten',10)
print m._dict
Output: 输出:
AttributeError: 'MyClass' object has no attribute '_dict'
Example2: 例2:
class MyClass(object):
_dict = {}
def __init__(self, key, value):
self._dict = self._dict.update({key:value})
m = MyClass('ten',10)
print m._dict
Output: None
输出: None
I am quite surprised with above behavior 我对上述行为感到非常惊讶
Why the example2 compiled successfully by just addition of _dict = {} line, and line present at class scope. 为什么仅通过添加_dict = {}行并在类作用域中显示行来成功编译example2。 also why None
output? 还为什么None
输出? I believed class scope variables has no relation with instance variable (special with self
) 我相信类范围变量与实例变量没有关系(特别是对self
)
Any Explaination? 有什么解释吗?
Your 'example 2' defines a single dictionary at the class level. 您的“示例2”在班级定义了一个字典。 All instances of the class will share that same dictionary, at least unless you reassign _dict on the instance. 该类的所有实例将共享同一词典,至少除非您在实例上重新分配_dict。
See this question for a detailed explanation: Why do attribute references act like this with Python inheritance? 有关详细说明,请参见此问题: 为什么属性引用在Python继承中表现得如此?
As for why you're getting None
- the update
method changes its dict in place, and returns None
. 至于为什么会得到None
,则update
方法将dict更改为原位,并返回None
。
The None
output is because dict.update
returns None. None
输出是因为dict.update
返回无。 It modifies the dictionary itself, but does not return anything. 它修改字典本身,但不返回任何内容。 So you probably wanted self._dict.update({key:value})
. 因此,您可能需要self._dict.update({key:value})
。 However, self._dict
doesn't exist at initialization. 但是, self._dict
在初始化时不存在。 So it would make more sense to do self._dict = {key: value}
. 因此,做self._dict = {key: value}
会更有意义。 If you're trying to modify the object's internal dictionary, then you should do self.__dict__.update({key:value})
. 如果您尝试修改对象的内部字典,则应执行self.__dict__.update({key:value})
。 However, this is bad practice. 但是,这是不好的做法。 A better idea would be to write setattr(self, key, value)
. 一个更好的主意是编写setattr(self, key, value)
。 The reason Example2 is working successfully is because if you try to do getattr(instance, thing)
(which is what instance.thing
does), and thing
is not in instance.__dict__
, then instance.__class__.__dict__
will be checked instead. Example2成功运行的原因是因为如果您尝试执行getattr(instance, thing)
instance.__class__.__dict__
getattr(instance, thing)
( instance.thing
所做的thing
),而thing
不在instance.__dict__
,则将改为检查instance.__class__.__dict__
。
因为示例2中的_dict
是类变量,所以它是MyClass
的属性,而示例1中的_dict是实例变量,因此它是实例属性。
Example 1: you are trying to update an object that is yet to be created. 示例1:您尝试更新一个尚未创建的对象。 therefore error. 因此错误。
Example 2: When working in the inner scope of the function, if you modify the variable it makes changes to the previously defined _dict. 示例2:在函数的内部范围内工作时,如果修改变量,它将更改先前定义的_dict。 But if you assign the value, it makes a new variable with the same name in the inner scope. 但是,如果您分配该值,它将在内部范围内创建一个具有相同名称的新变量。
This will work. 这将起作用。
class MyClass(object):
_dict = {}
def __init__(self, key, value):
self._dict.update({key:value})
This will not. 不会的。
class MyClass(object):
_dict = {}
def __init__(self, key, value):
self._dict = self._dict.update({key:value})
because you are doing an assigning operation. 因为您正在执行分配操作。 It makes a new variable. 它产生一个新变量。 So no changes are made to the _dict in the outer scope. 因此,不会在外部范围内对_dict进行任何更改。 Your _dict in the outer scope is still empty and returns None. 您在外部范围中的_dict仍然为空,并返回None。
self._dict
does not yet exist, so the first version raises that exception. self._dict
还不存在,因此第一个版本会引发该异常。 The second one actually falls through looking _dict
up on the instance and instead updates the class attribute, then assigns the class-level dictionary to the instance-scope _dict
attribute. 第二个实际上是通过在实例上查找_dict
,然后更新class属性,然后将类级字典分配给instance-scope _dict
属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.