在Python中:如何将用户输入转换为代码?
我有一个函数,需要在x和y的范围内进行双重积分,范围都是从-10到10。我正在使用SciPy里面的一个内置积分函数来完成这个工作。不过,具体需要积分的函数需要用户输入。
这个函数是A*cos(x+y),其中A是用户输入的内容。
比如,有时候A是一个常数,比如2。那么积分就是2*cos(x+y),范围还是从-10到10。我希望用户在被问到A的时候输入2。
但有时候,用户可能想让A等于sin(x)。那么积分就变成了sin(x)*cos(x+y),范围依然是从-10到10。我希望用户在被问到A的时候输入np.sin(x)。
或者用户可能需要A是np.pi*y*e^(x/3)。
用户输入的A是一个字符串。我该如何将这个字符串变成代码,这样如果用户输入np.sin(x),在后面的代码中进行积分时,Python能把它识别为np.sin(x)*np.cos(x+y)呢?
如果用户输入错误(比如把np.sin拼错成np.siin),返回一个错误我也是可以接受的。
我写的代码如下:
import numpy as np
from scipy.integrate import dblquad
A = input('Enter your function here: ')
def function(x,y):
return A*(np.cos(x+y))
integral = dblquad(function, -10, 10, lambda x:-10, lambda x:10)
print integral
感谢任何提供的帮助。
2 个回答
我很确定你可以用“eval”这个函数来实现这个功能。https://docs.python.org/2/library/functions.html#eval
不过要小心,这个函数会执行用户输入的内容,这可能会带来安全风险。
编辑:在你的函数里,把A变量替换成eval(A)。假设这是一个有效的函数,这样应该就能工作了。
我建议你可以尝试以下方法,这个方法不是绝对可靠,但应该能处理大部分情况:
- 首先,确保你使用的库已经导入。
对用户输入应用以下规则:
- 先试着用
int
把它转换成数字,如果失败了: - 看看输入中有没有
.
,如果有,就在这个.
处分开:- 如果
.
左边的部分不是一个模块,那就是无效输入。 - 取
.
右边的部分,然后截取到最后一个(
。 - 检查这个值是否是模块的一个属性,并且是可以调用的。如果不是,那就是无效输入。
- 如果是的话,使用
partials
来调用它,然后把你剩下的公式连接起来。
- 如果
- 如果输入中没有
.
,检查一下有没有(
,并截取到这个(
。 - 看看结果是否可以调用,使用
partials
来调用它。
- 先试着用
这里有一些代码:
import functools
import re
i = 'math.sin(12)'
try:
i = int(i)
except ValueError:
bits = i.split('.')
if len(bits) > 1:
module = bits[0]
callable = bits[1][:bits[1].rfind('(')]
args = re.search(r'\((.*?)\)', i).groups()[0]
if hasattr(module, callable):
f = functools.partial(getattr(module, callable), args)
到这里为止,f
就是你可以调用的函数。不过,这段代码有一些问题:
它没有考虑到所有情况,特别是如果用户输入了没有模块的函数,你需要处理这一部分。
它也没有处理复杂的嵌套函数调用。
希望你能在此基础上,根据你的具体需求进行改进。