【问题标题】:How do Python's class closures work?Python 的类闭包是如何工作的?
【发布时间】:2010-02-03 14:59:07
【问题描述】:

如果我针对本地命名空间创建一个类,它究竟是如何工作的?例如:

>>> def foo():
...     i = 1
...     class bar(object):
...             j = i
...     return bar
... 
>>> dis(foo)
  2           0 LOAD_CONST               1 (1)
              3 STORE_DEREF              0 (i)

  3           6 LOAD_CONST               2 ('bar')
              9 LOAD_GLOBAL              0 (object)
             12 BUILD_TUPLE              1
             15 LOAD_CLOSURE             0 (i)
             18 BUILD_TUPLE              1
             21 LOAD_CONST               3 (<code object bar at 0xb74f8800, file "<stdin>", line 3>)
             24 MAKE_CLOSURE             0
             27 CALL_FUNCTION            0
             30 BUILD_CLASS         
             31 STORE_FAST               0 (bar)

  5          34 LOAD_FAST                0 (bar)
             37 RETURN_VALUE        

我特别好奇的几行是:

             15 LOAD_CLOSURE             0 (i)
             18 BUILD_TUPLE              1
             21 LOAD_CONST               3 (<code object bar at 0xb74f8800, file "<stdin>", line 3>)
             24 MAKE_CLOSURE             0
             27 CALL_FUNCTION            0
             30 BUILD_CLASS

我想我想知道的最重要的事情是正在创建然后调用什么函数?这个函数是闭包附加到类的,还是发生在其他地方?

【问题讨论】:

    标签: python closures bytecode


    【解决方案1】:

    整个类体,即

    j = i
    

    是一个代码对象,它在偏移量 21 处加载,然后通过 CALL_FUNCTION 在偏移量 27 处调用。然后将调用的结果(本地命名空间)与类名和基一起使用来创建类。 BUILD_CLASS 接受三个参数,类似于type(name, bases, dict) 函数:

    返回一个新的类型对象。这本质上是类语句的动态形式。 name字符串是类名,成为name属性;基元组逐项列出基类并成为 bases 属性; dict 字典是包含类主体定义的命名空间,并成为 dict 属性。

    还有一篇非常详细的文章 "Notes on the Python Class Statement" 解释了类创建的工作原理。

    【讨论】:

      猜你喜欢
      • 2020-01-06
      • 2010-09-19
      • 2013-06-07
      • 2012-09-08
      • 1970-01-01
      • 2017-07-04
      • 2011-03-02
      相关资源
      最近更新 更多