本文是python解释器系列文章的一部分,第一部分文章请看这里:
http://blog.csdn.net/caimouse/article/details/47342357
从第一部分文章里可知,主要分析了一下函数对象相关的内容。本文里继续深入分析python解析器相关内容,主要分析函数的代码对象。
>>> def foo(a):
... x = 3
... return x + a
...
>>> foo
<function foo at 0x107ef7aa0>
>>> foo.func_code
<code object foo at 0x107eeccb0, file "<stdin>", line 1>
从上面这段代码里可以看到,代码对象是函数对象的一个属性(当然在函数对象里还有很多其它的属性,在这里暂时不关注那些属性)。
python解析器通过编译和解析之后生成代码对象,代码对象包含解析器执行代码时所需要的信息,让我们先来查看一下代码对象所包括的属性:
>>> dir(foo.func_code)
[‘__class__‘, ‘__cmp__‘, ‘__delattr__‘, ‘__doc__‘, ‘__eq__‘, ‘__format__‘, ‘__ge__‘,
‘__getattribute__‘, ‘__gt__‘, ‘__hash__‘, ‘__init__‘, ‘__le__‘, ‘__lt__‘, ‘__ne__‘, ‘__new__‘,
‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__sizeof__‘, ‘__str__‘,
‘__subclasshook__‘, ‘co_argcount‘, ‘co_cellvars‘, ‘co_code‘, ‘co_consts‘, ‘co_filename‘,
‘co_firstlineno‘, ‘co_flags‘, ‘co_freevars‘, ‘co_lnotab‘, ‘co_name‘, ‘co_names‘, ‘co_nlocals‘,
‘co_stacksize‘, ‘co_varnames‘]
从上面可以看到,这里有很多属性,也许你觉得这理解起来是有压力的,其实不必担心,今天我们只要讨论几个相关的属性即可。好的,这样就简单了。让我们先来看一下函数foo的代码对象,在这个代码对象里我们只关心下面几个属性:
>>> foo.func_code.co_varnames
(‘a‘, ‘x‘)
>>> foo.func_code.co_consts
(None, 3)
>>> foo.func_code.co_argcount
1
从这里可以看到这些相关的内容:函数foo变量的名称、函数里使用的常量以及函数有多少个参数。但是从这里我们没有看到任何可执行指令相关的属性,或者怎么样执行代码对象。我们知道解析器生成可执行的指令内容叫做字节码,这些字节码保存在代码对象的属性里:
>>> foo.func_code.co_code
‘d\x01\x00}\x01\x00|\x01\x00|\x00\x00\x17S‘
从这些表面的属性就可理解到很多了,为了更加深入了解代码对象,将会在第三部分继续讨论。
源文参看:
http://akaptur.com/blog/2013/11/17/introduction-to-the-python-interpreter-3/
蔡军生 微信号:shenzhencai 深圳
原文地址:http://blog.csdn.net/caimouse/article/details/48803945