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

标签 python class python-internals

与函数不同,类的主体在定义时执行:

class A(object):
    print 'hello'

输出:

hello

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

最佳答案

Everything 在 Python 首次导入模块时在模块级别执行。函数体(和生成器表达式体)是这里的异常(exception),而不是规则。 Python 执行一切以创建包含在模块中的对象;与 Python 中的所有内容一样,类是对象,函数也是。

类主体使用单独代码对象的唯一原因是因为类主体在单独的 namespace 中执行,然后该 namespace 形成类属性。类主体不是唯一的此类 namespace ; set 和 dict comprehensions,在 Python 3 中,列表推导式也使用单独的命名空间执行,限定其局部变量的范围。

所以函数和生成器表达式是异常(exception),明确地说是因为它们的整个目的 是在稍后执行。请注意函数定义执行:

>>> 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 字节码创建函数对象,连同该函数的存储字节码,结果绑定(bind)到全局名称 foo

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

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

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

关于python - 为什么类的主体在定义时执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26193653/

相关文章:

python - 枚举在 Python 2.7 中不可迭代

python - 如何测试我的代码

python - 为什么在 python 中导入 kivy 时会打印信息行?

python - 为什么 Python 3 中的 "1000000000000000 in range(1000000000000001)"这么快?

python - mac 上的多处理导入模块

python - 将多核与 LocalMRJobRunner 用于 MRJob

python - 将 dask delayed 与函数返回列表一起使用

java - 如何将Java写的 "ArrayList<ClassNod>"转成C++程序语言?

java - 对象被视为未初始化的变量

python - __next__ 和 __str__ 是否由等效的 next 和 str 函数在内部调用?