如何使用';输入';在Python3.x中输入数学函数作为变量

如何使用';输入';在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

我希望我的程序的用户输入一个他们选择的数学函数,用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 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呢?我们如何实现一个库?