Python解释器简介(2):代码对象


这是Python解释器简介的第二部分。第一部分请点击这里 。

完成编译之前的三个步骤都是在检查一个简单的函数对象。我们现在来谈谈更深层次的对象——函数的代码对象。

  1. >>> def foo(a): 
  2. ...     x = 3 
  3. ...     return x + a 
  4. ... 
  5. >>> foo 
  6. <function foo at 0x107ef7aa0
  7. >>> foo.func_code 
  8. <code object foo at 0x107eeccb0, file "<stdin>", line 1

从上面的代码,你能发现所谓的代码对象就是函数对象的一个属性。这个函数对象还有许多其它的属性,但它们大多都很无聊,因为 foo 函数实在是太简单了。)

代码对象是在Python编译器中生成的,并且在解释器中完成解释工作。它向解释器传递“开工了”的信息。我们再来看看代码对象的属性。

  1. >>> dir(foo.func_code) 
  2. ['__class__''__cmp__''__delattr__''__doc__''__eq__''__format__''__ge__'
  3. '__getattribute__''__gt__''__hash__''__init__''__le__''__lt__''__ne__''__new__'
  4. '__reduce__''__reduce_ex__''__repr__''__setattr__''__sizeof__''__str__'
  5. '__subclasshook__''co_argcount''co_cellvars''co_code''co_consts''co_filename'
  6. 'co_firstlineno''co_flags''co_freevars''co_lnotab''co_name''co_names''co_nlocals'
  7. 'co_stacksize''co_varnames'

这个属性列表虽然很长,但是其中大多数属性我们今天并不会涉及。我们只关注3个有趣的 foo 函数代码对象的属性。

  1. >>> foo.func_code.co_varnames 
  2. ('a''x'
  3. >>> foo.func_code.co_consts 
  4. (None3
  5. >>> foo.func_code.co_argcount 
  6. 1 

通过调用它们,我们能依次得到:变量名、函数中已知的常量和函数参数的数量。但是目前为止,我们还是不知道生成代码对象的指令到底是什么。事实上,这个指令叫做字节码。字节码也是代码对象的一个属性:

  1. >>> foo.func_code.co_code 
  2. 'd\x01\x00}\x01\x00|\x01\x00|\x00\x00\x17S' 

我们得到了许多待分解的信息。这里到底发生了什么?在下一部分,我们将深入研究字节码。

评论关闭