5

假设我在不同的场景中有 2 个类。

方案 1

class MyClass():
    temp = 5

方案 2

class MyClass():
    temp = 5

    def myfunc(self):
          print self.temp

现在何时将变量temp视为类变量和实例变量。我很困惑,因为在这两种情况下我都可以temp使用两者来访问变量的值。

  1. Object.Temp(表现为实例变量)

  2. ClassName.Temp(表现为类变量)

我相信以前也有人问过类似的问题,但如果有人能在我的问题的背景下解释这一点,那将是一个很大的帮助。

4

3 回答 3

6

类变量在类的所有实例之间共享。对于不可变类型(如 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成员,则使用类的成员。

因此,如果您进一步这样做:

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
于 2012-06-02T12:22:26.193 回答
5

基本上,MyClass.temp总是一个类变量。Gettingobj.temp返回类变量,直到您尝试 set 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 所说,调用方法(例如append()obj.temp不算作“设置”它。

于 2012-06-02T12:21:52.570 回答
2

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

于 2012-06-02T12:25:15.607 回答