理解 Python 中的实例变量和类变量

5
假设我有两个不同场景的类。 场景1
class MyClass():
    temp = 5

情境2

class MyClass():
    temp = 5

    def myfunc(self):
          print self.temp

现在,变量temp何时被视为类变量和实例变量我感到困惑,因为在这两种情况下,我都能够使用temp的值。
以下是两种情况:
1. Object.Temp(作为实例变量) 2. ClassName.Temp(作为类变量)
我相信类似的问题以前已经被问过,但如果有人能够解释一下这个问题,那将是一大帮助。
3个回答

5

类变量在类的所有实例之间共享。对于不可变类型(如int、str等),你不会注意到太大的区别。但是考虑以下情况:

class MyClass():
    temp = []  
    def myfunc(self, val):
          self.temp.append(val)
          print self.temp

instance1 = MyClass()
instance1.myfunc(1)    # [1]
instance2 = MyClass()
instance2.myfunc(2)    # [1, 2]

在这种情况下,两个实例共享同一个列表。也就是说,如果实例本身没有一个名为“temp”的成员,则使用类的“temp”成员。
因此,如果您进一步执行以下操作:
MyClass.temp.append(3)
print instance1.temp   # [1, 2, 3]
instance1.temp = []
print instance1.temp   # []         uses the instances temp
print instance2.temp   # [1, 2, 3]
del instance1.temp
print instance1.temp   # [1, 2, 3]  uses the class' temp again

2
这是一个列表,不是字典。非常好的答案,不过 :) - Lev Levitsky
1
那么为什么在我的第二个场景中需要 self 来访问 temp 变量呢?我理解 self 只是代表当前调用的对象。 - RanRag
1
@Noob,没有selftemp将总是指向一个局部变量。在Python中,你不会自动操作self(就像在Java中操作this一样)。 - mata
@mata:你能推荐一本好的教程或书籍来理解这些概念吗? - RanRag
@Noob - 从官方Python教程开始学习,或者将鼠标悬停在[tag:python]标签上并单击“信息”以获取参考资料。 - mata
显示剩余3条评论

4

基本上,MyClass.temp 总是一个类变量。获取 obj.temp 返回类变量,直到你尝试设置 obj.temp,这会创建一个成员变量来掩盖类变量。希望这能帮到你:

>>> class MyClass(object):
...     temp = 5
... 
>>> a = MyClass()
>>> b = MyClass()
>>> a.temp
5
>>> b.temp
5
>>> b.temp = 6
>>> a.temp
5
>>> MyClass.temp = 7
>>> a.temp
7
>>> b.temp
6
>>> a.__dict__
{}
>>> b.__dict__
{'temp': 6}
>>> MyClass.__dict__
{..., 'temp': 7}

编辑:如mata所说,在obj.temp上调用方法(例如append())不算是“设置”它。


1

temp 是一个类变量。当您访问该变量时,它会在继承层级中进行搜索,因此如果在实例本身中找不到它,则会检查类(上一层)并在那里找到它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接