一尘不染

为什么在定义时执行类的主体?

python

与函数相反,类的主体在定义时执行:

class A(object):
    print 'hello'

出:

hello

为什么会这样呢?它与@classmethod/@staticmethod方法和类属性有关吗?


阅读 317

收藏
2021-01-20

共1个答案

一尘不染

*Python首次导入模块时, *所有操作 均在模块级别执行。函数体(和生成器表达体)在这里是 例外
,而不是规则。Python执行所有操作以创建模块中包含的 对象 ;像Python中的所有内容一样,类是对象,函数也是。

类主体使用单独的代码对象的唯一原因是因为类主体是在单独的名称空间中执行的,然后该名称空间构成了类属性。类主体不是唯一的此类命名空间;set和dict理解,并且在Python
3中,列表理解也使用单独的命名空间执行,对本地变量进行范围界定。

因此,函数和生成器表达式是个例外,这是因为它们的全部 目的 将在以后执行。注意,该函数 的定义 执行:

>>> import dis
>>> dis.dis(compile('def foo(): pass', '<stdin>', 'exec'))
  1           0 LOAD_CONST               0 (<code object foo at 0x106aef2b0, file "<stdin>", line 1>)
              3 MAKE_FUNCTION            0
              6 STORE_NAME               0 (foo)
              9 LOAD_CONST               1 (None)
             12 RETURN_VALUE

MAKE_FUNCTION那里的字节码创建函数对象,以及该函数的存储字节码,结果绑定到全局名称foo

这里的类对象没有什么不同。该class语句产生一个类对象,作为该对象的一部分,我们需要从类主体中了解属性。

如果Python 执行类主体,则其他代码将无法使用这些类成员。您无法访问类属性(包括类方法和静态方法),无法 设置 类属性,等等。

当然,那时
执行属于类主体的任何功能。与顶级函数一样,仅MAKE_FUNCTION执行字节码,然后将所得的本地名称(设置为STORE_FAST)转换为类属性,类似于将全局函数对象绑定到带有的全局函数对象STORE_NAME

2021-01-20