Python中调用函数列表的惯用方法是什么?

4

当事件触发时,我有一系列回调函数需要调用。这是Python的惯用写法吗?

def first_callback(m):
  print 'first ' + m

def second_callback(m):
  print 'second ' + m

lst = [first_callback, second_callback]

map(lambda x: x("event_info"),lst) #is this how you do it?

参见:http://stackoverflow.com/questions/1785867/efficient-way-of-calling-set-of-functions-in-python/1785905#1785905 - Stephan202
4个回答

18

仅在没有副作用的函数(例如print)时使用map。也就是说,仅在函数只返回某些值的情况下使用它。在这种情况下,常规循环更符合语言习惯:

for f in lst:
    f("event_info")
Edit: 另外,从Python 3.0开始,map的返回值为迭代器而不是列表,因此在Python 3.0中,除非显式地评估生成器中的所有元素(例如通过将对map的调用封装在list中),否则问题中给出的代码将不会调用任何函数。幸运的是,2to3工具会对此发出警告:

文件 map.py:

map(lambda x: x, range(10))

2to3-3.0 map.py 输出:

RefactoringTool: Skipping implicit fixer: buffer
RefactoringTool: Skipping implicit fixer: idioms
RefactoringTool: Skipping implicit fixer: set_literal
RefactoringTool: Skipping implicit fixer: ws_comma
--- map.py (original)
+++ map.py (refactored)
@@ -1,1 +1,1 @@
-map(lambda x: x, range(10))
+list(map(lambda x: x, list(range(10))))
RefactoringTool: Files that need to be modified:
RefactoringTool: map.py
RefactoringTool: Warnings/messages while refactoring:
RefactoringTool: ### In file map.py ###
RefactoringTool: Line 1: You should use a for loop here

3

你也可以使用列表推导式:

[f("event_info") for f in lst]

然而,它确实有一个副作用,会返回一系列结果列表。

map()函数也会返回一个结果列表。Listcomp与原始问题等效。 - gimel

0
我必须询问这是否真正是OP的意图。当我听到“调用函数列表”时,我认为仅仅循环遍历函数列表并调用每个函数是如此显然,以至于问题肯定不止于此。例如,考虑到这两个字符串操作程序:
def reverse(s):
    return s[::-1]

import random
def randomcase(s):
    return ''.join(random.choice((str.upper, str.lower))(c) for c in s)

manips = [reverse, randomcase]
s = "Now is the time for all good men to come to."

# boring loop through list of manips
for fn in manips:
    print fn(s)

# more interesting chain through list of manips
s_out = s
for fn in manips:
    s_out = fn(s_out)
print s_out

第一个循环打印:
.ot emoc ot nem doog lla rof emit eht si woN
NOW IS THe tIMe for aLL good meN TO COme To.

第二个函数将第一个函数的输出链接到下一个函数的输入,并打印:
.oT EMoC OT NeM DOog lla RoF emit EHt SI won

这种方法允许您将几个简单的函数组合成更复杂的函数。


0

如果您有动态创建函数列表,那么简单的for循环就足够了:

for function in list_of_functions: function(your_argument_here)

但是,如果您使用面向对象编程(OOP),并且某些类应该知道某些事件发生(通常是更改),请考虑引入观察者设计模式: http://en.wikipedia.org/wiki/Observer_pattern

引入模式意味着将工作代码重构为该模式(即使未完全引入整个模式,也要在代码看起来不错时停止),请阅读Kerievsky的《重构到模式》以获取更多信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接