2009-05-22 3 views
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? 
+0

См. Также: http://stackoverflow.com/questions/1785867/efficient-way-of-calling-set-of-functions-in-python/1785905#1785905 – Stephan202

ответ

17

Используйте map только для функций без побочных эффектов (например, print). То есть, используйте его только для функций, которые просто что-то возвращают. В этом случае обычный цикл более идиоматический:

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 
+0

+1: Ударьте меня на 11 секунд! –

3

Вы также могли бы написать список понимание:

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

Однако, он имеет побочный эффект возврата lis т результатов.

+0

map() также возвращает список результатов. Listcomp эквивалентен исходному вопросу. – gimel

0

Если создается динамически список функций просто для хорошо:

для функции в list_of_functions: функция (your_argument_here)

Но если вы используете ООП и некоторые классы должны знать, что какое-то событие происходит (как правило, меняются) рассмотреть вопрос о создании шаблона проектирования Observer: http://en.wikipedia.org/wiki/Observer_pattern,

Представление шаблона означает реорганизацию рабочего кода к этому шаблону (и остановка, когда код выглядит хорошо, даже если не был введен целый текст) read больше в «Рефакторинге к узорам» Кериевского.

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 

Этот второй метод позволяет вам создавать более сложные функции из нескольких простых.

Смежные вопросы