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

usu*_* me 16 python class python-2.7 python-internals

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

class A(object):
    print 'hello'
Run Code Online (Sandbox Code Playgroud)

日期:

hello
Run Code Online (Sandbox Code Playgroud)

为什么会这样?它与@classmethod/ @staticmethodmethods和class属性有关吗?

Mar*_*ers 24

当Python首次导入模块时,一切都在模块级执行.函数体(和生成器表达式主体)在这里是例外,而不是规则.Python执行所有操作以创建模块中包含的对象 ; 就像Python中的所有东西一样,类是对象,函数也是如此.

类主体使用单独的代码对象的唯一原因是因为类主体在单独的命名空间中执行,然后该命名空间形成类属性.类主体不是唯一的这样的名称空间; set和dict comprehensions,在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        
Run Code Online (Sandbox Code Playgroud)

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

类对象在这里没有什么不同; 该class语句产生一个类对象,作为该对象的一部分,我们需要知道类体的属性.

如果Python的根本没有执行类体,其他代码不能作出任何使用这些类成员.您无法访问类属性(包括类方法和静态方法),无法设置类属性等.

当然,任何属于类主体的函数都不会在那时执行.就像顶级函数一样,只MAKE_FUNCTION执行一个字节码,然后将生成的本地名称(设置为STORE_FAST)转换为类属性,类似于绑定到全局函数的全局函数对象STORE_NAME.


fal*_*tru 8

根据类定义 - Python文档:

类定义是可执行语句.它首先评估继承列表(如果存在).继承列表中的每个项都应该计算为允许子类化的类对象或类类型.然后使用新创建的本地命名空间和原始全局命名空间,在新的执行框架中执行类的套件(请参阅命名和绑定一节).(通常,套件仅包含函数定义.)当类的套件完成执行时,其执行帧将被丢弃,但其本地名称空间将被保存.然后使用基类的继承列表和属性字典的已保存本地名称空间创建类对象.类名绑定到原始本地名称空间中的此类对象.