在Python中,如何在共享上下文中使用许多exec调用?

时间:2019-07-18 09:44:22

标签: python

我正在编写一个Python程序,以在Verilog脚本中执行嵌入式Python代码。我曾考虑使用evalexec函数,但遇到一个问题:我想让所有execeval在共享< em> context ,而无需更改主程序的环境。

我将execeval放在函数中以调用解析例程:

# some parsing code
for embedded_code_string in list_of_embedded_code_strings:
    execute_embedded_code(embedded_code_string)
# more parsing code
def execute_embedded_code(embedded_code_string):
    exec(embedded_code_string)
    # other routines involving io.StringIO for the redirection of stdout which isn't the problem.

如果要运行的第一个嵌入式代码字符串是row_len = 1,而第二个是column_len = row_len * 2,则在运行第二个代码片段时,row_len将是未定义的。可以预期:毕竟,exec在函数execute_embedded_code的上下文中运行,并且在函数完成后,变量将从locals()globals()中消失。

看来您可以为exec设置本地和全局名称空间。但是,运行exec后的更改将不会就地保留。 (更正:global_dict和local_dict参数必须为字典,否则将被忽略。如果它是字典,则将被就地更新。。)运行globals()和{{ locals()之后的1}}会捕获更改,但也会捕获解析程序中的对象,因此,我不希望嵌入的代码无意中弄乱了解析程序。

所以我的问题是,我将如何在它们的共享上下文中运行许多exec调用,但又要足够孤立以至于它们不会产生意想不到的后果。无需考虑安全性,因为运行中的所有嵌入式代码都将受到信任。

我想获得每个嵌入式代码字符串的单独输出,因此我不认为将它们连接在一起并一次运行就可以了。

1 个答案:

答案 0 :(得分:1)

您应该能够定义自己的共享FactoryBot.define do factory :my_model do bar { 'abc' } transient do default_values true end before(:create) do |my_model, evaluator| if evaluator.default_values? foo { 'abc' } end end trait(:foo_not_set) do transient do default_values { false } end end end end ,并将其传递给globals,然后由嵌入代码对其进行修改:

exec

输出

def execute_embedded_code(embedded_code_string, shared_globals):
    exec(embedded_code_string, shared_globals)

shared_globals = dict()
shared_globals['result'] = 0
sample_string = 'result += 1'
execute_embedded_code(sample_string, shared_globals)
print(shared_globals['result'])

注意

要在下面发表评论,请documentation for exec声明

  

如果仅提供 globals ,则必须为字典,该字典将用于全局变量和局部变量。