249 votes

Passer des fonctions avec des arguments à une autre fonction en Python ?

Est-il possible de passer des fonctions avec des arguments à une autre fonction en Python ?

Disons pour quelque chose comme :

def perform(function):
    return function()

Mais les fonctions à passer auront des arguments comme :

action1()
action2(p)
action3(p,r)

337voto

S.Lott Points 207588

Vous voulez dire ça ?

def perform(fun, *args):
    fun(*args)

def action1(args):
    # something

def action2(args):
    # something

perform(action1)
perform(action2, p)
perform(action3, p, r)

14 votes

Qu'en est-il des paramètres nommés ? C'est-à-dire, def action1(arg1, arg2=None, arg3=None) Comment pouvez-vous passer un argument que vous souhaitez voir affecté à arg3, par exemple ?

7 votes

Perform( fun, **args ), voir stackoverflow.com/questions/8954746/

0 votes

Et si perform et action1 , action2 sur des fichiers différents ? @S.Lott

165voto

Dave Points 5879

C'est à ça que servent les lambdas :

def perform(f):
    f()

perform(lambda: action1())
perform(lambda: action2(p))
perform(lambda: action3(p, r))

7 votes

Par ailleurs, par curiosité, pouvez-vous me dire pourquoi les lambdas ne conviennent pas dans ce cas ?

11 votes

Les lambdas sont l'une des meilleures caractéristiques des bons langages de programmation. malheureusement, l'implémentation de Python est sévèrement limitée. dans ce cas, cependant, ils s'adaptent parfaitement

3 votes

Je trouve que la syntaxe limitée est presque opaque ; elle est difficile à expliquer aux n00bz. Oui, ils fonctionnent ici, et les caractéristiques déroutantes de la syntaxe sont absentes. C'est -- peut-être -- le seul exemple que j'ai vu d'un lambda qui n'est pas obscur.

49voto

null Points 343

Vous pouvez utiliser la fonction partielle de functools comme suit.

from functools import partial

def perform(f):
    f()

perform(Action1)
perform(partial(Action2, p))
perform(partial(Action3, p, r))

Fonctionne également avec des mots-clés

perform(partial(Action4, param1=p))

1 votes

functools.partial est également plus polyvalent si perform doit transmettre d'autres paramètres à f . Par exemple, on pourrait appeler perform(partial(Action3, p)) et perform(f) pourrait faire quelque chose comme f("this is parameter r") .

13voto

Jochen Ritzel Points 42916

Utilisez functools.partial, pas lambdas ! Et bien sûr Perform est une fonction inutile, vous pouvez passer autour des fonctions directement.

for func in [Action1, partial(Action2, p), partial(Action3, p, r)]:
  func()

3 votes

Cela dépend si vous voulez que les arguments soient évalués à l'emplacement de l'appel de Perform ou non.

6voto

denis Points 7316

(des mois plus tard) un petit exemple réel où lambda est utile, partiel non :
disons que vous voulez diverses coupes transversales unidimensionnelles à travers une fonction bidimensionnelle, comme des tranches à travers une rangée de collines.
quadf( x, f ) prend un 1-d f et l'appelle pour diverses x .
L'appeler pour des coupes verticales à y = -1 0 1 et des coupes horizontales à x = -1 0 1,

fx1 = quadf( x, lambda x: f( x, 1 ))
fx0 = quadf( x, lambda x: f( x, 0 ))
fx_1 = quadf( x, lambda x: f( x, -1 ))
fxy = parabola( y, fx_1, fx0, fx1 )

f_1y = quadf( y, lambda y: f( -1, y ))
f0y = quadf( y, lambda y: f( 0, y ))
f1y = quadf( y, lambda y: f( 1, y ))
fyx = parabola( x, f_1y, f0y, f1y )

Pour autant que je sache, partial ne peut pas faire ça

quadf( y, partial( f, x=1 ))
TypeError: f() got multiple values for keyword argument 'x'

(Comment ajouter les balises numpy, partial, lambda à cela ?)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X