使用麻木.jit在用户输入字符串上

2024-10-06 12:27:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图编写一个程序,将用户输入函数作为一个字符串,并使用该函数进行大量计算。这些计算使用麻木.jit,如果我硬编码我的函数,代码就可以工作了,但是我很难找到如何解析字符串的方法,以便将它转换成一个nopython=True的jitted函数。在

例如,我的代码与函数一起运行

@jit(nopython=True)
def f(x):
    return x*x

但是我想用用户输入字符串'x*x'创建相同的函数。我试过使用SymPy,但是我不能让它很好地与jit一起使用。有什么想法吗?在


Tags: 方法函数字符串代码用户程序true编码
1条回答
网友
1楼 · 发布于 2024-10-06 12:27:01

假设你真的想把任意的Python代码作为用户输入并运行它,你通常真的,真的不想这样做,但是让我们假设你有一个很好的理由

但首先,你提到过要和辛普森一起做这件事。如果你真的试图用SymPy表达式创建函数,例如,通过使用sympify或{}-这应该可以工作,如果不起作用,如果你想得到调试它的帮助,你需要展示你的代码。在

但是,让我们停止拖延,让我们来看看你是如何做到你所要求的,即使这很可能不是你想要的。在


记住decorator只是函数,它接受一个函数并返回另一个函数,您可以正常调用它们。因此,您所要做的就是将任意Python代码转换为函数,然后将其传递给decorator。在


如果任意的Python代码只是一个表达式,那么可以将它包装在lambda表达式中,eval得到一个应用该表达式的函数:

lambdastr = f'lambda x: {user_string}'
lambdafunc = eval(lambdastr)
numbafunc = numba.jit(nopython=True)(lambdafunc)

或者,如果您愿意:

^{pr2}$

如果您认为“但是等等,eval是危险的”—嗯,是的,eval是危险的,因为它将任意用户字符串作为代码进行计算,这正是您想要做的。没有不危险的方法。在

因此,如果用户将字符串x * x传递给你,你现在就有了一个对其输入进行平方运算的函数,如果用户将字符串__import__('os').system('rm -rf /')传递给你,你就得到了一个函数,它试图擦除整个硬盘。在


如果您想获取一个语句,那么可以通过将其包装在def中并调用exec来有效地执行相同的操作:

defstr = f'def __(x): {user_string}'
deffunc = exec(defstr)
numbafunc = numba.jit(nopython=True)(deffunc)

如果任意Python代码可以是一个语句块,那么需要处理缩进这一事实会稍微复杂一些,但这并不难:

user_lines = '\n'.join(' '+line for line in user_string.splitlines())
defstr = f'def __(x):\n{user_lines}'
deffunc = exec(defstr)
numbafunc = numba.jit(nopython=True)(deffunc)

相关问题 更多 >