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

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

class A(object): print 'hello' 

date:

 hello 

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

当Python首先导入一个模块时, 一切都在模块级执行。 函数体(和生成器expression体)在这里是例外 ,而不是规则。 Python执行一切来创build模块中包含的对象 ; 就像Python中的所有东西一样,类是对象,function也是。

类体使用单独的代码对象的唯一原因是因为一个类体在一个单独的命名空间中执行,然后该命名空间形成类属性。 类体不是唯一的这样的命名空间; 设置和词典解释,而在Python 3中,列表parsing也是用一个单独的命名空间执行的,对其本地人进行范围化。

所以函数和生成器expression式是个例外,因为它们的整个目的是在晚些时候执行。 请注意,函数定义 执行:

 >>> 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字节码在那里创build函数对象,以及为该函数存储的字节码,并将结果绑定到全局名称foo

类对象在这里没有什么不同。 class声明产生一个类对象,并且作为该对象的一部分,我们需要知道类体中的属性。

如果Python没有执行类体,其他代码就不能使用这些类成员。 你不能访问类属性(包括类方法和静态方法),你不能设置类属性等。

任何作为类体的一部分的函数当然不会在当时被执行。 就像顶级函数一样,只有一个MAKE_FUNCTION字节码被执行,结果得到的本地名字(用STORE_FAST设置)然后变成一个类属性,类似于一个全局函数对象绑定到一个全局的STORE_NAME

根据类定义 – Python文档 :

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