Python 动态构造函数

5 投票
5 回答
1824 浏览
提问于 2025-04-15 15:12

我有几个小函数,分别叫做 f1f2f3,还有一个函数叫 f

我希望 f 能像一个“容器”,根据程序的配置来执行 f1f2f3 中的一些操作,比如可以选择执行 f1f2,或者 f1f3,甚至三个都执行,但不想做其他的事情。

我想到两种简单的解决办法:第一种是在 f 函数里加一些 if 语句:

if configuration_f1_f2:
    f1()
    f2()

第二种是我可以在 f 里加一个操作列表:

for op in operations:
    op()

然后根据配置把 f1f2f3 加到这个 operations 列表里,或者把它们移除。

但是我能不能以某种方式动态构建 f 的代码,直接添加对 f1f2f3 的调用,而不需要任何 iflistfor 循环?我想要的是一种实时的代码操作。如果我的配置是 "f1f3",我就把 f 的代码设置成:

f1()
f3()

当我的配置变成 "f2f3" 时,我再把 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

如果 f1f2 等是有副作用的函数,那么你应该使用明确的 for 循环(不要用那些花哨的 map 解决方案)。也许你想要的是这样的?

configurations = {
  'config_1': (f1, f2, f3),
  'config_2': (f1, f2),
}

def f(config='config_1'):
    for op in configurations[config]:
        op()

如果 f1f2 等函数需要接收参数,那么也许下面这个定义的 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(),它可以执行相应的代码片段。

撰写回答