gpt4 book ai didi

python - 使用非本地人执行 Python 代码

转载 作者:太空狗 更新时间:2023-10-30 01:31:49 27 4
gpt4 key购买 nike

假设我有三个字典abc。我想 exec() 一个代码片段,其中 a 是全局变量,b 是非本地变量,c 是本地人。这对全局变量和局部变量都没有问题,因为我只需要使用 exec(code, a, c) —— 但是 b 呢?如何使 b 中的值作为非局部变量对代码片段可见?

我认为这澄清了这个概念:

assert globals() == a and locals() == a
def foo():
assert globals() == a and locals() == b
def bar():
assert globals() == a and locals() == c
exec(code)

最佳答案

虽然它并不是完全使用非本地变量执行 Python 代码,但我能够重写 AST,使其按照我想要的方式运行。每个正在访问的变量和未在函数或类作用域中本地定义的变量都将被重写以访问映射。

这是一个演示可能用例的示例,其中 a 是优先于 b 的字典,并将接收所有变量赋值,但 的值>b 如果没有被 a 覆盖,仍然会被考虑在内。

from nr.datastructures.chaindict import ChainDict
from nr.ast.dynamic_eval import dynamic_exec

d1 = {'a': 42}
d2 = {'b': 'spam'}

code ='''
print(a, b) # prints 42 spam
a = 'egg'
b = 'ham'
'''

dynamic_exec(code, ChainDict(d1, d2))
assert d1 == {'a': 'egg', 'b': 'ham'}, d1
assert d2 == {'b': 'spam'}, d2

适用于 nr v2.0.4 (免责声明:我是该软件包的开发者)


再详细一点

dynamic_exec() 函数将使用 ast.parse() 解析 Python 代码,然后应用重写全局的 ast.NodeTransformer变量名。示例:

import os
from os import path

parent_dir = path.dirname(__file__)

def main():
filename = path.join(parent_dir, 'foo.py')
print(filename)

这将变成语义上等同于

的AST
import os; __dict__['os'] = os
from os import path; __dict__['path'] = path

__dict__['parent_dir'] = __dict__['path'].dirname(__dict__['__file__'])

def main():
filename = __dict__['path'].join(__dict__['parent_dir'], 'foo.py')
__dict__['print'](filename)

关于python - 使用非本地人执行 Python 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48597347/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com