Python的类闭包是如何工作的?

6
如果我针对本地命名空间创建一个类,它是如何工作的?例如:
>>> 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

我想知道的最大问题是正在创建和调用什么函数?这个函数是闭包附加到类的地方,还是在其他地方发生?

1个回答

2
整个类的主体,即。
j = i

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

返回一个新的类型对象。这实际上是类语句的动态形式。名称字符串是类名并成为名称属性;基类元组列举了基类并成为基类属性;字典包含类体定义的命名空间,并成为字典属性。

还有一篇非常详细的文章“关于Python类语句的注释”解释了类的创建方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接