类变量vs实例变量--Python

时间:2012-09-30 01:11:12

标签: python

我在下面的例子中尝试了这个并且需要一些澄清。在这两种情况下,我都能够在测试函数中访问类变量和实例。

所以,假设我必须定义一个需要在所有函数中使用的文字,这将是更好的定义自身变量或类变量的方法吗?

code.py

class testclass:
    classvar = 'its classvariable LITERAL'
    def __init__(self,x,y):
        self.z = x
        self.classvar = 'its initvariable LITERAL'

        self.test()

    def test(self):
        print('class var',testclass.classvar)
        print('instance var',self.classvar)

if __name__ == '__main__':
    x = testclass(2,3)

4 个答案:

答案 0 :(得分:9)

我知道这是一个古老的...但我在1999年由Guido van Rossum(http://legacy.python.org/doc/essays/ppt/acm-ws/sld001.htm)做的一个旧的演讲中发现了这一点,我认为它很好地解释了这个话题:

实例变量规则

通过实例(self.x)使用​​,搜索顺序:

  • (1)实例,(2)类,(3)基类
  • 这也适用于方法查找

通过实例分配(self.x = ...):

  • 始终生成实例变量
  • 类变量“默认”用于实例变量

但是...!

  • 可变类变量:所有
  • 共享的一个副本
  • 可变实例变量:每个实例都有自己的

答案 1 :(得分:5)

类变量非常适合所有实例使用的“常量”(所有方法都是技术上的)。您可以使用模块全局变量,但使用类变量可以更清楚地与类关联。

实际上你也经常使用类变量,但通常最好远离它们,原因与你通过改变全局变量来避免程序的不同部分进行通信的原因相同。

实例变量适用于实际属于实例的数据。对于每个特定实例,它们可能不同,并且它们通常在单个特定实例的生命周期中发生变化。最好将实例变量用于概念上属于实例的数据,即使在您的程序中恰好只有一个实例,或者您有一些实际上总是具有相同值的实例。

答案 2 :(得分:3)

如果希望在所有实例之间共享它,则应将其定义为类属性。如果要为每个实例分别设置一个实例变量,则应将其定义为实例变量(例如,如果不同的实例可能具有不同的变量值)。

答案 3 :(得分:3)

如果要保持修复,只使用类属性是一种好习惯,关于它们的一个好处是它们可以在实例外部访问:

class MyClass():
    var1 = 1
    def __init__(self):
        self.var2 = 2

MyClass.var1 # 1 (you can reference var1 without instantiating)
MyClass.var2 # AttributeError: class MyClass has no attribute 'var2'

如果定义MyClass.var,则MyClass的每个实例都应该相同,否则会出现以下被认为令人困惑的行为。

a = MyClass()
b = MyClass()

a.var1, a.var2 # (1,2)
a.var1, a.var2 = (3,4) # you can change these variables
a.var1, a.var2 # (3,4)
b.var1, b.var2 # (1,2) # but they don't change in b
MyClass.var1 # 1         nor in MyClass