这个
co_const
属性只保存代码对象中定义的常量文本,因此在您的示例中,它只保存加载
'say foo'
作为return的参数,可以用
dis
:
import dis
for obj in code_obj.co_consts:
if isinstance(obj, types.CodeType):
dis.dis(obj)
这将输出:
5 0 LOAD_CONST 1 ('say foo')
2 RETURN_VALUE
所以通过执行这个代码对象,它自然不会定义任何名称。
如果只想在给定的源代码中执行特定的函数,可以使用
ast.parse
并使用
ast.NodeVisitor
子类来提取函数节点,用
Module
节点,以便您可以单独编译和执行它:
import ast
class get_function(ast.NodeVisitor):
def __init__(self, name):
self.name = name
self.code = None
def visit_FunctionDef(self, node):
if node.name == self.name:
self.code = compile(ast.fix_missing_locations(ast.Module(body=[node])), '<string>', 'exec')
func = get_function('foo')
func.visit(ast.parse(code, '<string>'))
exec(func.code)
print(eval('foo'))
这将输出:
<function foo at 0x018735D0>
编辑:或者更简单地说,您可以使用
ast.walk
函数来遍历节点
for
循环:
import ast
for node in ast.walk(ast.parse(code, '<string>')):
if isinstance(node, ast.FunctionDef) and node.name == 'foo':
code_obj = compile(ast.fix_missing_locations(ast.Module(body=[node])), '<string>', 'exec')
exec(code_obj)
print(eval('foo'))