我目前正在尝试用tkinter编写一个Python(3.4.4)GUI,它应该允许将任意函数适合某些数据点。为了简单起见,我想创建一些输入函数并对其求值。稍后,我想用curve_fit
从scipy
绘制并调整它。在
为此,我想从用户输入字符串创建一个动态(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
:
这里讨论的另一种方法types.FunctionType
(10303248)也没有成功。。。在
所以,我的问题是:对于这个场景,有没有一个好的替代方案?或者,如果没有,我如何使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:
你的例子和我的第一个例子很相似。但在我的理解中,这不是“动态的”,也就是说,当代码运行时,不能改变函数的输出。在
@沙丘:
我认为这是正确的方向,谢谢。但是,我还不明白下一步如何计算和使用这个函数?我的意思是:为了能够拟合它,我必须提取拟合变量(即a
在f(x)=a*x+b
)或在不同的x值下计算函数(即print(f(3.14))
)。在
exec/eval的问题是它们可以执行任意代码。因此,要使用
exec
或eval
,您需要仔细分析代码片段以确保它不包含恶意代码(这是一项非常困难的任务),或者确保代码的源是可信的。如果你在制作一个个人使用的小程序,那就没问题了。一个负责敏感数据或资金的大型程序,绝对不是。看起来你的用例被视为拥有一个可信的来源。在如果您只想在运行时创建一个任意函数,那么只需使用lambda表达式和
eval
的组合。例如您的尝试无效的原因是
^{pr2}$locals()
,在函数上下文中,创建了本地名称空间的副本。对生成的字典的更改不会影响当前的本地命名空间。你需要做一些类似的事情:我不知道你到底想做什么,也就是说,允许什么功能,允许什么操作,等等
以下是具有一个动态参数的函数生成器的示例:
相关问题 更多 >
编程相关推荐