在Python中动态定义函数名和函数体
我有以下几个函数
def foo_001(para):
tmp = para + 2
return tmp
def foo_002(para):
tmp = para * 2
return tmp
def foo_003(para):
tmp = para / 2
return tmp
def foo_004(para):
tmp = para - 2
return tmp
这些函数的名字不同,但算法的部分,比如“tmp = para - 2”,其他的部分都是一样的。
所以,我想知道我是否可以这样做:
def $fooname (para): # $ is borrowed try to say fooname is a variable
$alog # $algo is also variable
return tmp
lst = [
['tmp = para + 2', "foo_001"],
['tmp = para * 2', "foo_002"],
['tmp = para / 2', "foo_003"],
['tmp = para - 2', "foo_004"],
]
在运行时,我可以用 lst[0][0]
来赋值给 $algo
,然后用 lst[0][1]
来赋值给 $fooname
,这样我就可以通过 lst[0][x]
来调用列表里的函数吗?
关于我问题的更具体说明
文件 foo.py
def foo_001(para): tmp = para + 2 return tmp
def foo_002(para): tmp = para * 2 return tmp
def foo_003(para): tmp = para / 2 return tmp
...
def foo_100(para): tmp = #complex algo, return tmp
main.py
from foo import *
fun_name = ["foo_001","foo_002","foo_002" ... "foo_100"]
src = 1
rzt = []
for i in fun_name:
rzt.extent(eval(i)(src))
以下是我的问题:
- 我能在运行时获取
fun_name
列表吗?我想把它们保存到一个文本文件里。 - 我发现函数定义中有一个共同的部分,就是
tmp = #algo
。我能把它们提取出来,同时在运行时定义函数吗?我想要类似这样的东西:
文件 foo.py
def foo_factory():
# in somehow
return adict #function_name/function pair
template = [
["foo_001","tmp = para + 2"],
["foo_002","tmp = para * 2"],
["foo_002","tmp = para * 2"],
...
["foo_100","tmp = #complex algo"]
main.py
from foo import *
dic = foo_factory(template)
fun_name = dic.keys()
src = 1
rzt = []
for i in fun_name:
rzt.extent(eval(i)(src))
#or
rzt.extent(dic(i)())
5 个回答
0
我觉得你真正想做的是把函数本身放在一个列表里,然后从这个列表中取出你想要的函数。
foo_container = [foo_001,foo_002,foo_003,foo_004]
然后从这里,调用:
foo_container[0](3)
就和下面这个一样:
foo_001(3)
1
你现在在考虑字符串处理和命名函数,但其实应该考虑使用更高级的、没有名字的函数。这样做会简单很多,而且不需要用到动态特性哦;实际上,用Haskell语言来写的话,代码会更短更简洁。
举个例子:
import operator as op
def algo_factory(f):
def algo(para):
return f(para, 2)
#maybe, for nicer debugging output: algo.__name__ = "..."
return algo
algorithms = [
mkAlgo(op.add),
mkAlgo(op.mul),
mkAlgo(op.truediv),
mkAlgo(op.sub),
#...
]
另外,根据你正在做的事情,你可能会希望algorithms
是一个字典。
1
如果你在“创建时”不知道这些函数的名字,你打算怎么调用它们呢?
是不是更好的办法是把一组函数(闭包)放在一个数组里,根据需要来设置参数呢?
也就是说(虽然没测试过,但应该可以用):
def make_foo_func(op):
def func(para):
tmp = op(para, 2)
return tmp
return func
然后:
import operator
foo_001 = make_foo_func(operator.add)
foo_oo2 = make_foo_func(operator.mul)
...