【发布时间】:2013-04-01 10:28:46
【问题描述】:
作为this question I asked earlier 的后续行动,我正在尝试执行 Python 代码,就好像它在外部函数的上下文中一样。为此,我只需用def outer(): 包装一段代码,并进行一些简单的字符串处理以正确缩进内部代码。然后我编译它并通过执行co_consts列表中的第一个代码对象来执行编译后的内部代码。
例子:
mycode = """
print("Hey!")
"""
wrapped_code = 'def outer():\n ' + '\n '.join(mycode.strip().split('\n'))
compiled_code = compile(wrapped_code, '<str>', 'exec')
exec(compiled_code.co_consts[0], {}, {})
这会在外部函数的上下文中执行代码print("Hey")。 (如果有人想知道我为什么要这样做,它是我一直在研究的 C 扩展模块的一部分。)
问题:我遇到的一个问题是,如果我将代码包装在外部函数中,然后执行内部代码块,我似乎无法通过执行上下文的任何局部变量。
mycode = """
print(locals())
"""
wrapped_code = 'def outer():\n ' + '\n '.join(mycode.strip().split('\n'))
compiled_code = compile(wrapped_code, '<str>', 'exec')
exec(compiled_code.co_consts[0], {}, {"foo" : "bar"})
这个输出:
{}
请注意,我将包含{"foo" : "bar"} 的本地字典明确传递给exec,但是当它实际执行代码并打印locals() 时,它显示的是一个空字典。为什么Python没有使用我传递的局部变量字典?
【问题讨论】:
-
“如果有人想知道我为什么要这样做,那是我一直在研究的 C 扩展模块的一部分。” - 这并不能回答问题。我从未见过任何扩展模块可以做到这一点。
-
见 Include/code.h 和 Objects/frameobject.c (
PyFrame_New, 693-710)。 -
@eryksun,谢谢。你的评论解决了我的问题。我需要做的就是将函数代码对象中的
co_flags变量设置为0,这样它将使用我传递给它的本地字典,而不是为执行帧创建一个新的本地字典。
标签: python python-3.x