在Python中调用函数列表的惯用方法是什么?
我有一组回调函数,当某个事件发生时,我需要调用这些函数。这种写法在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?
4 个回答
0
如果你有一个动态创建的函数列表,使用简单的for循环就很好:
for function in list_of_functions:
function(your_argument_here)
但是如果你在使用面向对象编程(OOP),并且有一些类需要知道某个事件发生了(通常是一些变化),那么可以考虑引入观察者设计模式:http://en.wikipedia.org/wiki/Observer_pattern。
引入这种模式意味着你需要对现有的代码进行一些调整,使其符合这种模式(可以在代码看起来不错的时候停止,即使没有完全实现整个模式)。想了解更多,可以看看Kerievsky的《Refactoring to patterns》一书。
3
你也可以用一种叫做列表推导式的方法来写:
[f("event_info") for f in lst]
不过,这样做会有一个副作用,就是它会返回一个结果的列表。
18
使用 map
函数时,最好只用在那些没有副作用的函数上,比如 print
。也就是说,map
适合用在那些只返回结果的函数上。在这种情况下,使用普通的循环会更符合习惯:
for f in lst:
f("event_info")
补充说明:从 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