Python, Comment passer un argument à un paramètre de pointeur de fonction?

je viens juste de commencer à apprendre Python et j'ai découvert que je peux passer une fonction comme paramètre d'une autre fonction. Maintenant, si je l'appelle foo(bar()) il ne va pas passer comme un pointeur de fonction, mais la valeur de retour de la fonction utilisée. Appel de foo(bar) passera la fonction, mais de cette façon je ne suis pas en mesure de passer des arguments supplémentaires. Que faire si je veux passer un pointeur de fonction qui appelle bar(42)?

je veux la capacité de répéter une fonction indépendamment des arguments que j'ai passés à il.

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

def foo(s):
        print s

repeat(foo("test"), 4)

Dans ce cas, la fonction foo("test") est censé être appelé 4 fois dans une rangée. Est-il un moyen pour accomplir cela sans avoir à passer "test"repeat au lieu de <!--6?

29
demandé sur Benjamin 2012-12-09 03:55:03

3 réponses

vous pouvez utiliser un lambda:

repeat(lambda: bar(42))

Ou functools.partial:

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

Ou passer les arguments séparément:

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

ce style final est assez courant dans la bibliothèque standard et les principaux outils Python. *args indique un nombre variable d'arguments, vous pouvez donc utiliser cette fonction comme

repeat(4, foo, "test")

ou

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

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

notez que je mets le nombre de répétitions à l'avant pour plus de commodité. Il ne peut pas être le dernier argument si vous souhaitez utiliser le *args construire.

(pour être complet, vous pouvez ajouter des arguments de mots-clés aussi bien avec **kwargs.)

47
répondu Fred Foo 2012-12-09 14:54:34

vous devrez passer les paramètres pour foo, à la fonction repeat:

#! /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)
14
répondu Hyperboreus 2012-12-09 00:00:32

alors que beaucoup de réponses ici sont bonnes, celle-ci pourrait être utile parce qu'elle n'introduit pas de répétition inutile et la raison pour les rappels en premier lieu est souvent de synchroniser avec d'autres travaux en dehors du thread principal de L'UI.

Profitez-en!

importer temps, enfilage

def callMethodWithParamsAfterDelay(méthode=None, params=[], secondes=0.0):

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

Déf cancelDelayedCall (timer):

timer.cancel()

Exemple

def foo (a, b):

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

callMethodWithParametersAfterDelay (foo, ['roses', 'red'], 0)

1
répondu Peter Sichel 2018-01-08 13:13:48