在Python中动态定义函数名和函数体

3 投票
5 回答
6357 浏览
提问于 2025-04-16 06:06

我有以下几个函数

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)) 

以下是我的问题:

  1. 我能在运行时获取 fun_name 列表吗?我想把它们保存到一个文本文件里。
  2. 我发现函数定义中有一个共同的部分,就是 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)
...

撰写回答