【问题标题】:class variable vs instance variable --Python类变量与实例变量——Python
【发布时间】:2012-09-30 01:11:12
【问题描述】:

我在下面的示例中尝试了这个,需要澄清一下。在这两种情况下,我都可以访问测试函数中的类变量和实例。

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

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)

【问题讨论】:

    标签: python


    【解决方案1】:

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

    实例变量规则

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

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

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

    • 总是创建一个实例变量
    • 实例变量的类变量“默认”

    但是……!

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

    【讨论】:

      【解决方案2】:

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

      您也经常更改类变量的用途,但通常最好远离它们,原因与您远离通过更改全局变量来让程序的不同部分进行通信的原因相同。

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

      【讨论】:

        【解决方案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
        

        【讨论】:

        • b 获得自己的类变量“实例”?
        • @Reb.Cabin 不,它们是全球性的。
        • a.var1b.var1 不同,但正如您的示例所示,我认为b.var1MyClass.var1 相同(至少我的实验与该想法一致)。因此,以某种方式将3 分配给a.var1 会产生特定于实例a 的内容。能多解释一下吗?
        • @Reb.Cabin 这是不可变和可变之间的区别,3 是不可变的 int。因此,替换成为每个实例。如果你把它做成一个列表并附加到不同的实例上,你会看到它们共享可变状态。
        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2011-02-12
          • 1970-01-01
          • 2014-09-21
          • 2013-03-24
          • 2012-01-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多