Python 动态构造函数
我有几个小函数,分别叫做 f1
、f2
和 f3
,还有一个函数叫 f
。
我希望 f
能像一个“容器”,根据程序的配置来执行 f1
、f2
和 f3
中的一些操作,比如可以选择执行 f1
和 f2
,或者 f1
和 f3
,甚至三个都执行,但不想做其他的事情。
我想到两种简单的解决办法:第一种是在 f
函数里加一些 if
语句:
if configuration_f1_f2:
f1()
f2()
第二种是我可以在 f
里加一个操作列表:
for op in operations:
op()
然后根据配置把 f1
、f2
、f3
加到这个 operations
列表里,或者把它们移除。
但是我能不能以某种方式动态构建 f
的代码,直接添加对 f1
、f2
和 f3
的调用,而不需要任何 if
、list
或 for
循环?我想要的是一种实时的代码操作。如果我的配置是 "f1
和 f3
",我就把 f
的代码设置成:
f1()
f3()
当我的配置变成 "f2
和 f3
" 时,我再把 f
的代码修改成:
f2()
f3()
我能这样操作函数的代码吗?
5 个回答
1
要实现你想要的功能,有很多种方法,但首先你得把问题和背景说清楚。
一种方法可能是这样的,其他大多数方法都是这个的变种,使用一个字典来查找我们需要的函数。
def f1(): print "f1"
def f2(): print "f2"
def f3(): print "f3"
def f(fList):
for f in fList: globals()[f]()
f(["f1", "f2"])
f("f1 f3 f1 f3 f2 f1 f3 f2".split())
3
如果 f1
、f2
等是有副作用的函数,那么你应该使用明确的 for
循环(不要用那些花哨的 map
解决方案)。也许你想要的是这样的?
configurations = {
'config_1': (f1, f2, f3),
'config_2': (f1, f2),
}
def f(config='config_1'):
for op in configurations[config]:
op()
如果 f1
、f2
等函数需要接收参数,那么也许下面这个定义的 f
更合适:
def f(config, *args, **kwargs):
for op in configurations[config]:
op(*args, **kwargs)
3
如果你敢于尝试,可以把一个函数的定义写成一个 字符串,然后把它传给 exec
这个语句。比如:
func = "def f():\n"
if config_f1:
func += " f1()\n"
if config_f2:
func += " f2()\n"
exec func in globals()
到这个时候,你应该有了一个新的全局函数 f()
,它可以执行相应的代码片段。