41 votes

Fonctions Python avec plusieurs crochets de paramètres

J'ai du mal à comprendre ce que signifie h(a)(b) . Je n'en avais jamais vu avant hier, et je n'ai pas pu déclarer une fonction de cette façon:

 def f (a)(b):
    return a(b)
 

Quand j'ai essayé de faire def f (a, b): , cela n'a pas fonctionné non plus. Qu'est-ce que ces fonctions font? Comment puis-je les déclarer? Et, enfin, quelle est la différence entre f(a, b) et f(a)(b) ?

84voto

Markus Meskanen Points 7166

Fonctions avec plusieurs paramètre entre parenthèses n'existent pas, comme vous l'avez vu lorsque vous avez essayé d'en définir un. Il ya, cependant, les fonctions qui retournent des (autres) fonctions:

def func(a):
    def func2(b):
        return a + b
    return func2

Maintenant, lorsque vous appelez func() il retourne à l'intérieur func2 fonction de:

>>> func2 = func(1)  # You don't have to call it func2 here
>>> func2(2)
3

Mais si vous n'avez pas besoin de la fonction intérieure plus tard, alors il n'y a pas besoin de l'enregistrer dans une variable et vous pouvez les appeler directement l'un après l'autre:

>>> func(1)(2)   # func(1) returns func2 which is then called with (2)
3

C'est un très commun de l'idiome lors de la définition des décorateurs prendre des arguments.


Notez que l'appelant func() toujours crée une nouvelle fonction interne, même si ils sont tous nommés func2 à l'intérieur de la définition de notre - func:

>>> f1 = func(1)
>>> f2 = func(1)
>>> f1(1), f2(1)
(2, 2)
>>> f1 is f2
False

Et, enfin, quelle est la différence entre f(a, b)et f(a)(b)?

Il devrait être clair maintenant que vous savez ce qu' f(a)(b) , mais pour résumer:

  • f(a, b) des appels f avec deux paramètres, a et b
  • f(a)(b) des appels f avec un paramètre a, qui renvoie alors une autre fonction, qui est alors appelée avec un seul paramètre b

19voto

chepner Points 54078

f(a)(b) signifie simplement que l'expression f(a) renvoie une valeur qui est elle-même appelable. C'est une forme courte de

g = f(a)
g(b)

Vous pourriez être plus à l'aise en ajoutant une paire de redondant entre parenthèses à souligner que ce n'est pas une simple construction syntaxique.

(f(a))(b)  # f(a) is evaluated first, then the result is applied to b

C'est exactement analogue à la même doublement de crochets pour l'indexation des dictionnaires imbriqués.

d1[x][y]

est équivalent à

d2 = d1[x]
d2[y]

8voto

keksnicoh Points 602

Disons que nous avons une expression comme

f(a)(b)

ensuite, f(a) retourne une fonction qui est appelé avec un argument b. Considérons l'exemple suivant

def f(a):
   def g(b):
      return a * b
   return g

Ensuite, f(5)(4) évalue 5 * 4, depuis f(5) retourne une fonction qui est essentiellement

def g(b):
   return 5 * b

On pourrait maintenant faire des trucs comme ça

mult_by_5 = f(5)
[mult_by_5(x) for x in range(10)]

Soyons chics, qu'en plus de fonctions imbriquées?:

def f(a):
  def g(b):
    def h(c):
      return a * b *c
    return h
  return g
f(2)(3)(4) # 24

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