文章目录
- 简介
- 规则
- 思路
- 示例代码与运行效果
简介
运行Python时,在程序运行过程中手动输入一个函数表达式,并将其作为一个函数进行后续的调用工作,类似于Matlab里面的匿名函数。这个功能使用传统语言会相当麻烦,当然,我也只是利用了Python的某些功能进行了一些技巧性的操作,大家会发现,正式因为Python的这些有用的函数,动态创建函数成为可能。
规则
创建函数时,乘号依旧是不能省略的,可以使用常规的表达式,例如"3*x^2"表示3x23x^23x2,“2^x”表示2x2^x2x,"e^x"表示exe^xex,"ln(x)"表示lnxlnxlnx。支持复数的四则运算,但是若复数在指数上需要自己额外编写函数以适应计算。
当动态创建函数完成时,在交互式界面要求能任意调用函数值,若测试成功,则可在剩下的程序中扩展其他功能使用。调用形式类似于以下形式:
2**x-8*x+x^2-3
>>> f(9)
518.0
>>> f(0)
-2.0
>>> for i in range(0,11):print("f(%.3f)=%.3f"%(i,f(i)))f(0.000)=-2.000
f(1.000)=-8.000
f(2.000)=-11.000
f(3.000)=-10.000
f(4.000)=-3.000
f(5.000)=14.000
f(6.000)=49.000
f(7.000)=118.000
f(8.000)=253.000
f(9.000)=518.000
f(10.000)=1041.000
思路
我们需要实现的功能类似于在系统编程(ISP),但使用过于复杂的算法是不可取的,在此笔者提供一种非常简单的方法。首先介绍一下eval()函数,这是一个非常简单的函数,可以将输入的一串表达式转换为结果值(python3),例如(eval(“1+1”)=2),eval(“2**3”)=8。更有价值的一点是,如果import了math模块,可以直接把math模块的函数引入eval表达式,例如eval(“log10(100)”=2)。既然我们可以将一个特殊的用户自定义表达式计算出来,为什么我们不能将其作为一个函数呢?因此,格式化字符串与其结合就成了最好的选择。例如:
>>> str = "2*%d"
>>> eval(str % 2)
4
>>> eval(str % 10)
20
这个思路有了之后,我们基本上就汇编写我们的自定义函数程序了。
示例代码与运行效果
"""
手动设置函数
输入一个数学函数并调用它的值
Examples
[in0]:9*x+2*x^2
[in1]:f(1)
[out1]:11
[in2]:f(2)
[out2]:26
"""
from math import *
import matplotlib.pyplot as plt
from pylab import *
init_str = input("请输入一个函数,默认变量为x:\n") # 将所有的x替换为格式化符号
str_fx = init_str.replace("^", "**")def f(x):fx = str_fx.replace("x", "%(x)f") # 所有的"x"换为"%(x)f"return eval(fx % {"x": x}) # 字典类型的格式化字符串,将所有的"x"替换为变量xdef draw(a, b, interp):x = [a+ele*interp for ele in range(0, int((b-a)/interp))]y = [f(ele) for ele in x]plt.figure(1)plt.plot(x, y)xlim(a, b)title(init_str, color="b")plt.show()
运行效果如下:
请输入一个函数,默认变量为x:
>? atan(x)+pi*x/2-sin(x)+0.02*2^x
>>> for i in range(0,11):print(f(i))0.02
1.5547235053844484
3.4194439445582017
5.980314744723077
8.685805466155546
10.826306675582638
12.389841108348575
14.32748696103622
18.143453699983926
25.425187561533313
38.20311205314207
请输入一个函数,默认变量为x:
atan(x)-log(2*x+1)+3*x^2-4*x
draw(0,1,0.01)
显示绘制的函数图形如下:
可以看出本函数实现了用户在运行过程中创建函数的功能,绘图和调用只是最基本的两个功能,读者可在本基础上进行扩展。
转载请注明出处。