2012-12-08 12 views
27

Dopiero zacząłem uczyć się Pythona i odkryłem, że mogę przekazać funkcję jako parametr innej funkcji. Teraz, jeśli zadzwonię pod foo(bar()), to nie przejdzie jako wskaźnik funkcji, ale wartość zwracana użytej funkcji. Wywołanie funkcji foo(bar) przejdzie przez tę funkcję, ale w ten sposób nie będę mógł przekazać żadnych dodatkowych argumentów. Co zrobić, jeśli chcę przekazać wskaźnik funkcji, który wywołuje bar(42)?Python, jak przekazać argument do parametru wskaźnika funkcji?

Chcę możliwość powtarzania funkcji niezależnie od argumentów, które do niej przekazałem.

def repeat(function, times): 
    for calls in range(times): 
     function() 

def foo(s): 
     print s 

repeat(foo("test"), 4) 

W tym przypadku funkcja foo("test") ma być nazywane 4 razy z rzędu. Czy istnieje sposób, aby to osiągnąć bez konieczności przechodzenia "testu" na repeat zamiast foo?

+4

Strona poprzednia: Nie są to" f " wskaźniki unction "! W Pythonie funkcje są obiektami. –

Odpowiedz

42

Można też użyć lambda:

repeat(lambda: bar(42)) 

Albo functools.partial:

from functools import partial 
repeat(partial(bar, 42)) 

lub przekazać te argumenty oddzielnie:

def repeat(times, f, *args): 
    for _ in range(times): 
     f(*args) 

Ten ostatni styl jest dość powszechne w standardzie biblioteka i główne narzędzia Pythona. *args oznacza zmienną liczbę argumentów, więc można użyć tej funkcji jako

repeat(4, foo, "test") 

lub

def inquisition(weapon1, weapon2, weapon3): 
    print("Our weapons are {}, {} and {}".format(weapon1, weapon2, weapon3)) 

repeat(10, inquisition, "surprise", "fear", "ruthless efficiency") 

Zauważ, że mogę umieścić liczbę powtórzeń z góry dla wygody. Nie może być ostatnim argumentem, jeśli chcesz użyć konstrukcji *args.

(Dla kompletności, można dodać argumenty słów kluczowych, jak również z **kwargs).

14

Będziesz musiał przekazać parametry do foo, aby Funkcja powtarzania:

#! /usr/bin/python3.2 

def repeat (function, params, times): 
    for calls in range (times): 
     function (*params) 

def foo (a, b): 
    print ('{} are {}'.format (a, b)) 

repeat (foo, ['roses', 'red'], 4) 
repeat (foo, ['violets', 'blue'], 4) 
+0

Świetna odpowiedź. Powinien zdobyć więcej głosów! :) –

1

Chociaż wiele z odpowiedzi tutaj są dobre, ten może być pomocny, ponieważ nie wprowadza żadnych niepotrzebnych powtórzeń, a powód wywołań zwrotnych w pierwszej kolejności często jest synchronizowany z innymi pracami poza głównym wątkiem UI.

Ciesz się!

czasie importu, gwintowanie

def callMethodWithParamsAfterDelay (method = None, params = [] s = 0.0)

return threading.Timer(seconds, method, params).start() 

def cancelDelayedCall (zegar)

timer.cancel() 

Przykład

def foo (a, b)

print ('{} are {}'.format (a, b)) 

callMethodWithParametersAfterDelay (bla [ 'róż "," czerwony "], 0)

Powiązane problemy