ex的替代品

2024-10-01 11:26:37 发布

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

我目前正在尝试用tkinter编写一个Python(3.4.4)GUI,它应该允许将任意函数适合某些数据点。为了简单起见,我想创建一些输入函数并对其求值。稍后,我想用curve_fitscipy绘制并调整它。在

为此,我想从用户输入字符串创建一个动态(fitting)函数。我发现并阅读了exec,但人们说(1)使用它不安全,(2)总有更好的替代品(例如here和许多其他地方)。所以,我想知道在这种情况下有什么选择?在

下面是一些包含两个嵌套函数的示例代码,它们可以工作,但不是动态的:

def buttonfit_press():
    def f(x):
         return x+1
    return f 

print(buttonfit_press()(4))

在我开始使用xval之前,这里有一些代码会产生NameError: name 'f' is not defined

^{pr2}$

这里讨论的另一种方法types.FunctionType10303248)也没有成功。。。在

所以,我的问题是:对于这个场景,有没有一个好的替代方案?或者,如果没有,我如何使exec的代码运行?在

我希望这是可以理解的,不要太含糊。提前感谢您的想法和意见。在


@Gábor Erdős:

要么我不明白,要么我不同意。如果我在主循环中编写同一段代码,它将识别f,并且我可以从execstr执行代码段:

actfitfunc = "f(x)=x+1"
execstr = "def {}:\n    return {}\n".format(actfitfunc.split("=")[0], actfitfunc.split("=")[1])
exec(execstr)
print(f(4))
>>> 5

@ukasz-Rogalski:

打印execstr对我来说似乎不错:

def f(x):
    return x+1

缩进错误不大可能是由于我的编辑,但我仔细检查了一下-没问题。 引入my_locals,在exec中调用它并随后打印显示:

{'f': <function f at 0x000000000348D8C8>}

但是,我仍然得到NameError: name 'f' is not defined。在


@user3691475:

你的例子和我的第一个例子很相似。但在我的理解中,这不是“动态的”,也就是说,当代码运行时,不能改变函数的输出。在


@沙丘:

我认为这是正确的方向,谢谢。但是,我还不明白下一步如何计算和使用这个函数?我的意思是:为了能够拟合它,我必须提取拟合变量(即af(x)=a*x+b)或在不同的x值下计算函数(即print(f(3.14)))。在


Tags: 函数代码namereturnisdefnot动态
2条回答

exec/eval的问题是它们可以执行任意代码。因此,要使用execeval,您需要仔细分析代码片段以确保它不包含恶意代码(这是一项非常困难的任务),或者确保代码的源是可信的。如果你在制作一个个人使用的小程序,那就没问题了。一个负责敏感数据或资金的大型程序,绝对不是。看起来你的用例被视为拥有一个可信的来源。在

如果您只想在运行时创建一个任意函数,那么只需使用lambda表达式和eval的组合。例如

func_str = "lambda x: x + 1" # equates to f(x)=x+1
func = eval(func_str)
assert func(4) == 5 

您的尝试无效的原因是locals(),在函数上下文中,创建了本地名称空间的副本。对生成的字典的更改不会影响当前的本地命名空间。你需要做一些类似的事情:

^{pr2}$

我不知道你到底想做什么,也就是说,允许什么功能,允许什么操作,等等

以下是具有一个动态参数的函数生成器的示例:

>>> def generator(n):
        def f(x):
            return x+n
        return f
>>> plus_one=generator(1)
>>> print(plus_one(4))
5

相关问题 更多 >