Python的类闭包是如何工作的?
如果我在一个本地命名空间里创建一个类,这到底是怎么运作的呢?比如说:
>>> 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的位置被加载,然后在偏移量27的位置通过 CALL_FUNCTION
被调用。调用的结果(局部命名空间)会和类名以及基类一起用来创建这个类。BUILD_CLASS
接受三个参数,和 type(name, bases, dict)
函数类似:
返回一个新的类型对象。这基本上是类语句的一种动态形式。名称字符串就是类名,它会成为 name 属性;基类的元组列出了基类,并成为 bases 属性;而字典则是包含类体定义的命名空间,成为 dict 属性。
还有一篇非常详细的文章 “关于Python类语句的说明”,解释了类是如何创建的。