类属性与具有缺省值的实例变量的差异 [英] Difference between class attribute and instance variable with default value

查看:28
本文介绍了类属性与具有缺省值的实例变量的差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  1. 类变量和具有默认值的实例变量有什么区别吗?

(尤其是在"正常使用"下的行为,在内部我认为它们很可能是以不同的方式实现的)

  1. 我应该在什么上下文中使用哪个版本?

以这两个类为例:

class A:
    d = 4

class A:
    def __init__(self, d=4):
        self.d = d

无论您选择哪个版本,当您运行下面的代码时,都会得到相同的结果:

a2 = A()

a = A()
print(a.d)   # 4
a.d = 2
print(a.d)   # 2

print(a2.d)  # 4

我是在读了

后想到这个问题的。
  1. class attribute behavior

推荐答案

类变量和具有默认值的实例变量有什么区别吗?

嗯,显然是的:一个类属性(不是"变量")属于类,一个实例属性属于实例。

我应该在什么上下文中使用哪个版本?

如果希望属性由类的所有实例共享,则使用类属性;如果希望属性特定于该实例,则使用实例属性。实际上,您很少需要类属性。

请注意,如果同时为类和实例定义相同的属性,则实例上的属性将隐藏类的属性。

nb:以上是一个非常粗略的简化,但我需要解释整个Python对象模型,这值得一本完整的书

以这两个类为例(...)无论您选择哪个版本,当您运行下面的代码时,您都会得到相同的结果

是的,这是这段代码的预期结果。

对于a

在第一种情况下,当您第一次打印a.d时,a没有实例属性d,因此您将获得class属性值。然后,通过为其赋值来创建实例属性a.d,从那时起,它将隐藏类属性。

在第二种情况下,a.d最初具有其缺省值,然后将其重新绑定到另一个值...很普通的东西。

对于a2

在第一种情况下,a2.a将始终为4,因为您尚未使用实例属性对其进行跟踪,因此它将从类中获取值。

在第二种情况下,它将始终是4,因为您没有重新绑定实例属性,因此它仍然是默认值。

现在尝试将列表用作属性,并将其追加到列表,而不是重新绑定它:

class A:
    d = []

class B:
    def __init__(self):
        self.d = []


def test(cls):
    print("test {}".format(cls.__name__))
    a = cls()
    print(a.d)   
    a.d.append(2)
    print(a.d)   
    a2 = cls()
    print(a2.d)  

if __name__ == "__main__":
    test(A)
    test(B)
最后要注意的是:您可能已经看到(或者有一天您可能会看到)使用类属性作为实例的默认值的代码--或者您可能会自己尝试这样做(因此提到了实例属性的‘默认’值)--如您的第一个示例所示。这是不好的做法。这充其量是令人困惑的,如果属性是可变类型,则可能导致错误的行为。

这篇关于类属性与具有缺省值的实例变量的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆