我已经做了类似的事情来对事件应用任意过滤规则,以查看是否需要采取行动作为响应。事件和相关上下文将作为参数传递给从包装在 lambda 中的任意表达式编译的函数。
# API consists of the variables:
# - plant
# - root
# - currentTime
# math.* and random.* are imported
exprs = """\
sin(currentTime()*360) - (plant.height*5 + root.depth**2)
cos(currentTime()*180) - (plant.height*3 + root.depth**(1.5 + random()*0.5))""".splitlines()
# function to 'compile' expression into an executable function
def makeFunction(expr):
# define args that are supported in the expression
api = "plant,root"
return eval("lambda %s : %s" % (api, expr))
# compile given expressions into functions
fns = [makeFunction(e) for e in exprs]
这是一个模拟包装器,用于展示它在您的大型程序中的外观:
from math import *
from random import *
# mock up simple classes and vars to simulate larger program
def simpleClass(clsname, **kwargs):
classDefn = "class %s:\n %s=%s" % (clsname, ','.join(kwargs.keys()),
','.join(map(str,kwargs.values())))
print classDefn
exec(classDefn, globals())
def mockProgramVars():
# define some simple classes for API variables
simpleClass("Plant", height=0, stem=0)
simpleClass("Root", depth=0, thickness=0, radius=0)
return Plant(), Root()
plant, root = mockProgramVars()
# loop through time, evaluating functions as plant and root grow
for T in range(0,10):
# note, local vars become implicit part of API for functions
def currentTime():
return T
# define explicit args
args = (plant, root)
# invoke compiled functions
print T, ":",
for i,fn in enumerate(fns, start=1):
print fn(*args),
print
# have plant grow a bit before next time
plant.height += 0.1
root.depth += 0.2
印刷:
class Plant:
stem,height=0,0
class Root:
depth,radius,thickness=0,0,0
0 : 0.0 1.0
1 : 0.418915723414 -0.948727984564
2 : -1.70407169644 -1.12048780375
3 : -2.5102191366 -0.418297794419
4 : -1.72700555043 -2.69830945686
5 : -3.36779764724 -2.4337532978
6 : -5.42800370907 -2.38542932493
7 : -5.03162665152 -4.90632786047
8 : -5.81504769652 -4.46741225807
9 : -8.59104601264 -5.02132453755
当然,所有关于使用 eval 的标准警告都适用。