如何将变量指定为类或类实例的成员变量?

时间:2016-08-23 19:11:33

标签: python python-2.7

在最新的Python 2.7.x中:

  1. 给定一个类定义中的任何成员变量,成员变量总是在类级别,因为它是由类的所有实例共享的单个变量吗?

  2. 在类的定义中,如何指定

    • 类的定义中的哪些成员变量属于该类,因此由该类的所有实例共享,并且
    • 属于该类的特定实例而不属于该类的另一个实例?
  3. 如何引用类的成员变量?

    如何引用类实例的成员变量?

  4. 上述问题的答案是否出现在官方python语言参考https://docs.python.org/2/reference/中? 我在那里找不到它们。

  5. 感谢。

1 个答案:

答案 0 :(得分:2)

您可能想要使用terminology"类变量"和"实例变量"在这里,因为它是python中的常用语言。

class Foo(object):

    var1 = "I'm a class variable"

    def __init__(self, var2):
        self.var2 = var2  # var2 is an instance variable

你在python中真正需要知道的唯一范围规则是名称的查找顺序 - " LEGB",用于Local,Enclosing,Global和Builtin。

类范围变量var1仍然必须通过" get属性"进行查找,您只能通过Foo.var1self.var1访问该属性。当然,您也可以在类定义块中的其他位置访问它,但这只是来自" Local"范围。

当您看到self.var1时,您无法立即知道它是实例还是类变量(实际上,如果名称完全绑定到对象,也不会!)。您只知道在尝试使用该类之前,会在对象本身上尝试使用get属性。

实际上,实例变量可以隐藏同名的类变量:

>>> f1 = Foo(var2='f1_2')
>>> f2 = Foo(var2='f2_2')
>>> f2.var1
"I'm a class variable"
>>> f2.var1 = "Boom!"  # this shadows the class variable
>>> f1.var1, Foo.var1, f2.var1  # but: the class variable still exists
("I'm a class variable", "I'm a class variable", 'Boom!')
>>> del f2.var1  # restores the name resolution on the Foo object
>>> f2.var1
"I'm a class variable"

为了使问题复杂化,我们可以编写花哨的代码,使类变量的行为更像实例变量;一个值得注意的例子是"字段"一个ORM。例如,在Django中,您可以在model类上定义一个整数字段 - 但是当您在模型的实例上查找该名称时,您会得到一个返回的实际整数(不是{{1}对象)。

如果您对此属性访问的高级用法感兴趣,请阅读descriptor protocol。对于平凡的类,您可以安全地忽略这些细节,但是值得知道实例变量和类变量的通常解析具有低于优先级比可能已在类上定义的任何描述符。

相关问题