代码之家  ›  专栏  ›  技术社区  ›  minou

python子类对父类变量的访问

  •  31
  • minou  · 技术社区  · 14 年前

    当我得知子类的类变量不能访问父类的类变量时,我很惊讶,因为没有明确指出父类的类名:

    >>> class A(object):
    ...     x = 0
    ... 
    >>> class B(A):
    ...     y = x+1
    ... 
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in B
    NameError: name 'x' is not defined
    >>> class B(A):
    ...     y = A.x + 1
    ... 
    >>> B.x
    0
    >>> B.y
    1
    

    2 回复  |  直到 14 年前
        1
  •  30
  •   Nathan Davis    14 年前

    在Python中,类的主体在创建类之前在其自己的命名空间中执行(之后,该命名空间的成员成为类的成员)。因此,当解释器到达y=x+1时,类B此时还不存在,因此没有父类。

    http://docs.python.org/reference/compound_stmts.html#class-definitions

        2
  •  51
  •   Alex Martelli    14 年前

    Python对barenames的作用域规则非常简单明了:首先是本地名称空间,然后是嵌套当前名称的外部函数(如果有的话),然后是全局函数,最后是内置函数。这就是查找一个裸名时所发生的一切,不需要记忆或应用任何复杂的规则(也不需要Python编译器强制执行更复杂的规则)。

    任何时候你想要一个不同的查找,你将使用 光秃秃的 姓名。限定名的功能要强大得多,因为查找总是可以委托给可以请求其属性的对象,而这些对象可以实现它们所需要的任何查找规则。特别是在类中的实例方法中, self.x 这个 问问题的方式 self 要查找属性名称的对象 'x' --在这种查找中,它可以委托给类,包括继承概念的实现(以及多重继承、方法解析顺序等等)。

    身体 class 声明, 类对象被创建或其名称被绑定(特别是,在任何基被定义为基之前——无论如何,在引用barenames时,这个最新的细节永远都不重要!-).

    在你的例子里,在课堂上 B ,光名 x 是用通用规则查找的--是本地绑定的名称吗?如果否,是否在嵌套此作用域的任何外部函数中绑定?如果没有,它是作为一个全局的还是内置的绑定?如果以上都没有,使用有问题的barename当然会导致名称错误异常。

    A.x 然而 在那一点上,毕竟。。。通常是元类 type ,当它被调用时,它会将基绑定作为其工作的一部分 类主体执行完毕!-).

    有些人非常热衷于其他“神奇的”裸名查找规则,以至于他们无法忍受Python的这一方面(我相信,最初是受到Modula-3的启发,Modula-3是一种鲜为人知的语言,在理论家的圈子里得到了很好的考虑;-)——不得不写作 自我.x 一定要仰望 例如,与其使用通用的裸名规则,不如让这些人变得暴躁。

    任何 其他形式的查找。。。但是,我疯狂地爱上Python并不是什么秘密(我也有自己的抱怨——例如。, global x 一句话总是让我毛骨悚然,我宁愿写在那里 global.x global 是“当前正在执行的模块”的内置名称。。。我