TypeError消息中提到的“代码对象”是什么?
在使用Python的exec
语句时,我遇到了以下错误:
TypeError: exec: arg 1 must be a string, file, or code object
我不想传入一个字符串或文件,但什么是代码对象?我该如何创建一个?
4 个回答
18
代码对象的相关信息可以在这里找到:
代码对象代表的是经过字节编译的可执行Python代码,也就是字节码。代码对象和函数对象的区别在于,函数对象里有一个明确的引用,指向它的全局变量(也就是它被定义的模块),而代码对象没有任何上下文。此外,函数对象里还存储了默认参数值,而这些默认值并不在代码对象里,因为它们是在运行时计算出来的。与函数对象不同,代码对象是不可变的,并且不包含对可变对象的引用(无论是直接的还是间接的)。
30
Dan Crosta写了一篇很棒的博客,详细讲解了这个话题,包括如何手动创建代码对象,以及如何将它们拆解回来:
37
创建一个代码对象的一个方法是使用内置的 compile
函数:
>>> compile('sum([1, 2, 3])', '', 'single')
<code object <module> at 0x19ad730, file "", line 1>
>>> exec compile('sum([1, 2, 3])', '', 'single')
6
>>> compile('print "Hello world"', '', 'exec')
<code object <module> at 0x19add30, file "", line 1>
>>> exec compile('print "Hello world"', '', 'exec')
Hello world
另外,函数还有一个叫做 __code__
的属性(在旧版本中也叫 func_code
),通过这个属性你可以获取到函数的代码对象:
>>> def f(s): print s
...
>>> f.__code__
<code object f at 0x19aa1b0, file "<stdin>", line 1>