【问题标题】:How to dynamically define functions?如何动态定义函数?
【发布时间】:2011-04-10 21:39:46
【问题描述】:

我有这样的功能:

def activate_field_1():
   print 1

def activate_field_2():
   print 2

def activate_field_3():
   print 3

如何为x=1:10 定义activate_field_[x],而无需逐一输入?当然,我更愿意传递一个参数,但出于我的目的,这是不可能的。

【问题讨论】:

  • 您在评论中说要静态定义它们,但随后又提到这样做会浪费源文件中的空间。是哪个?
  • 什么是“动态函数”?你能解释一下这句话的意思吗?
  • 这个问题似乎是重复的:stackoverflow.com/questions/11291242/…

标签: python


【解决方案1】:

您想在源文件中单独静态定义这些吗?那么你最好的选择是编写一个脚本来生成它们。

另一方面,如果您希望在运行时使用这些函数,则可以使用更高阶的函数。例如

>>> def make_func(value_to_print):
...     def _function():
...         print value_to_print
...     return _function
...
>>> f1 = make_func(1)
>>> f1()
1
>>> f2 = make_func(2)
>>> f2()
2

您可以在运行时再次生成并存储这些列表。

>>> my_functions = [make_func(i) for i in range(1, 11)]
>>> for each in my_functions:
...     each()
...
1
2
3
...

【讨论】:

  • 是的,我想在源文件中静态定义它们。我可以编写脚本,尽管这么多函数会浪费空间。感谢您解释如何在运行时执行此操作。
【解决方案2】:

这里的函数名称​​完全如您所愿(并且比@Goutham 现已删除的答案中提到的Dynamic/runtime method creationaccepted answer 简单一点):

FUNC_TEMPLATE = """def activate_field_{0}(): print({0})"""
for x in range(1, 11): exec(FUNC_TEMPLATE.format(x))

>>> activate_field_1()
1
>>> activate_field_7()
7

在 Python 3.6+ 版本中,可以使用所谓的f-string 文字如下所示编写:

for x in range(1, 11): exec(f"""def activate_field_{x}(): print({x})""")

【讨论】:

  • 正是我需要动态生成用于单元测试的测试用例函数,谢谢。
  • 这很好,我也可以用装饰器定义函数。
  • 请记住,这种方法不适合生产代码。
【解决方案3】:

您可以将新符号放入vars()返回的当前变量绑定字典中:

for i in range(1, 11):
    def f(x):
        def g():
            print x
        return g
    vars()['activate_field_%d' % i] = f(i)

>>> activate_field_3()
3

但是这个技巧一般不推荐,除非你确定你需要它。

【讨论】:

  • 你真的不需要需要[重新]定义f() 10次......
【解决方案4】:

也许你可以根据自己的需要调整这个食谱。

from functools import partial
class FunctionPool:
    def __init__(self,function):
        self.function = function
    def __getitem__(self,item):
        return partial(self.function,item)

>>> @FunctionPool
def func(item,param):
    print "function#{item} called with {param}".format(
        item = item,
        param = param )
>>> f = func[2]
>>> f(3)
function#2 called with 3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    • 1970-01-01
    • 2013-03-22
    • 2011-01-01
    相关资源
    最近更新 更多