如何使用';输入';在Python3.x中输入数学函数作为变量
我希望我的程序的用户输入一个他们选择的数学函数,用numpy表示法,这样我就可以对它进行操作。例如:如何使用';输入';在Python3.x中输入数学函数作为变量,python,numpy,input,Python,Numpy,Input,我希望我的程序的用户输入一个他们选择的数学函数,用numpy表示法,这样我就可以对它进行操作。例如: import numpy as np f=eval(input("Please input your function in numpy notation") >>> "Please input your function in numpy notation" >>> np.exp(x) >>> NameError: name 'x' is
import numpy as np
f=eval(input("Please input your function in numpy notation")
>>> "Please input your function in numpy notation"
>>> np.exp(x)
>>> NameError: name 'x' is not defined
通过上面的代码,用户正在输入指数函数,它被保存到变量“f”——更一般地说,我希望任何数学函数都作为输入,并以某种方式存储为python函数。这方面的伪代码可能类似于:
def F(x):
f = eval(input("Please enter function in numpy notation:"))
return f
如果我们再次以指数函数为例,这相当于硬编码:
def F(x):
return np.exp(x)
def F(x):
return x*np.sin(x)
为了清楚起见,再举一个例子
def F(x):
f = eval(input("Please enter function in numpy notation:"))
return f
>>> x*np.sin(x)
用户在命令行上输入x*np.sin(x),这相当于硬编码:
def F(x):
return np.exp(x)
def F(x):
return x*np.sin(x)
还有其他方法吗?考虑使用
例如:
In [23]: import numexpr as ne
In [24]: a = np.arange(1e6)
In [25]: s = "sin(a)**2 + cos(a)**2"
In [27]: res = ne.evaluate(s)
In [28]: res
Out[28]: array([ 1., 1., 1., ..., 1., 1., 1.])
In [29]: res.shape
Out[29]: (1000000,)
它通常也比Numpy快:
In [32]: %timeit ne.evaluate(s)
11.4 ms ± 256 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [33]: %timeit np.sin(a)**2 + np.cos(a)**2
41 ms ± 1.15 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
考虑使用
例如:
In [23]: import numexpr as ne
In [24]: a = np.arange(1e6)
In [25]: s = "sin(a)**2 + cos(a)**2"
In [27]: res = ne.evaluate(s)
In [28]: res
Out[28]: array([ 1., 1., 1., ..., 1., 1., 1.])
In [29]: res.shape
Out[29]: (1000000,)
它通常也比Numpy快:
In [32]: %timeit ne.evaluate(s)
11.4 ms ± 256 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [33]: %timeit np.sin(a)**2 + np.cos(a)**2
41 ms ± 1.15 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
当您执行f=eval(输入(“请输入numpy表示法中的函数”)
时,用户的输入会被解释为您已将其写入文件中。因此,如果用户输入x+1
,那么python脚本将尝试在该行中执行x+1
如果您希望该行创建函数,您的用户将必须输入计算结果为实际函数的内容。这可能类似于lambda x:x+1
,它返回一个带有一个参数(x)的函数,计算x+1
。当然,您也可以在代码中添加lambda x:
。小例子:
def F(x):
return eval("lambda x:" + input("Please input a function in numpy notation!"))
x = 1
f = F(x)
print(f(x))
当然,这需要始终将变量称为x
如果执行上述代码并输入例如x+1
,则输出为2。当执行f=eval(输入(“请输入numpy符号中的函数”)
时,用户的输入将被解释为您已将其写入文件中。因此,如果用户输入x+1
,那么python脚本将尝试在该行中执行x+1
如果您希望该行创建函数,您的用户将必须输入计算结果为实际函数的内容。这可能类似于lambda x:x+1
,它返回一个带有一个参数(x)的函数,计算x+1
。当然,您也可以在代码中添加lambda x:
。小例子:
def F(x):
return eval("lambda x:" + input("Please input a function in numpy notation!"))
x = 1
f = F(x)
print(f(x))
当然,这需要始终将变量称为x
如果您执行上述代码并输入例如
x+1
,则输出为2。一个简单的解决方案是将eval
包装在函数中,让它访问名称x
和np
:
import numpy
i = input("fn: ") # enter function once
def f(x):
return eval(i, {'x': x, 'np': numpy})
f(42) # call it
f(0) # call it again...
请注意,eval
非常不安全。没有任何东西可以阻止用户输入恶意代码。如果你对安全(或性能)有点在意,@MaxU的答案更可取
如果计划经常调用该函数,则有必要对其进行预编译:
i = input("fn: ") # enter function once
i = compile(i, 'input', 'eval')
生成的代码对象可以像字符串一样传递给eval
输入的计时np.exp(x)
:
一个简单的解决方案是,我们只需将
eval
包装到一个函数中,并允许它访问名称x
和np
:
import numpy
i = input("fn: ") # enter function once
def f(x):
return eval(i, {'x': x, 'np': numpy})
f(42) # call it
f(0) # call it again...
请注意,eval
非常不安全。没有任何东西可以阻止用户输入恶意代码。如果你对安全(或性能)有点在意,@MaxU的答案更可取
如果计划经常调用该函数,则有必要对其进行预编译:
i = input("fn: ") # enter function once
i = compile(i, 'input', 'eval')
生成的代码对象可以像字符串一样传递给eval
输入的计时np.exp(x)
:
. 无论何时,当您需要从外部源执行任意输入时,都是时候重新考虑您的策略和目标了。那么
eval(“os.system('rm-rf/'))”
?-)@zwer呢,因为终端的目的是从外部源执行任意输入,从您的角度来看,终端不应该存在吗?我认为缺少了一些上下文,关于如何使用程序来真正判断这类问题。。。。无论何时,当您需要从外部源执行任意输入时,都是时候重新考虑您的策略和目标了。那么eval(“os.system('rm-rf/'))”
?-)@zwer呢,因为终端的目的是从外部源执行任意输入,从您的角度来看,终端不应该存在吗?我认为缺少了一些上下文,关于如何使用编程来真正判断这类问题……如果函数是cos或sin呢?我们如何实现一个库?如果函数是cos或sin呢?我们如何实现一个库?