He tenido problemas para entender lo que significa h(a)(b) . Nunca había visto uno de esos antes de ayer, y no podía declarar una función de esta manera:
def f (a)(b): return a(b) Cuando traté de hacer def f (a, b): , tampoco funcionó. ¿Qué hacen estas funciones? ¿Cómo puedo declararlos? Y, finalmente, ¿cuál es la diferencia entre f(a, b) y f(a)(b) ?
Las funciones con múltiples paréntesis de parámetros no existen, como vio cuando trató de definir uno. Sin embargo, hay funciones que devuelven (otras) funciones:
def func(a): def func2(b): return a + b return func2 Ahora, cuando llamas a func() , devuelve la función func2 interna:
>>> func2 = func(1) # You don't have to call it func2 here >>> func2(2) 3Pero si no necesita la función interna más adelante, entonces no es necesario guardarla en una variable y puede llamarlas una tras otra:
>>> func(1)(2) # func(1) returns func2 which is then called with (2) 3Este es un modismo muy común al definir decoradores que toman argumentos.
Tenga en cuenta que llamar a func() siempre crea una nueva función interna, aunque todas se func2 dentro de la definición de nuestra func :
>>> f1 = func(1) >>> f2 = func(1) >>> f1(1), f2(1) (2, 2) >>> f1 is f2 FalseY, finalmente, ¿cuál es la diferencia entre
f(a, b)yf(a)(b)?
Debería quedar claro ahora que sabe lo que f(a)(b) , pero para resumir:
f(a, b) llama a f con dos parámetros a y bf(a)(b) llama a f con un parámetro a , que luego devuelve otra función, que luego se llama con un parámetro bf(a)(b) simplemente significa que la expresión f(a) devuelve un valor que en sí mismo es invocable. es una forma corta de
g = f(a) g(b)Es posible que se sienta más cómodo agregando un par de paréntesis redundantes para enfatizar que no se trata de una única construcción sintáctica.
(f(a))(b) # f(a) is evaluated first, then the result is applied to bEs exactamente análogo a la misma duplicación de corchetes para indexar diccionarios anidados.
d1[x][y]es equivalente a
d2 = d1[x] d2[y]Digamos que tenemos una expresión como
f(a)(b) luego, f(a) devuelve una función en sí misma que se invoca con el argumento b . Considere el siguiente ejemplo
def f(a): def g(b): return a * b return g Entonces f(5)(4) se evalúa como 5 * 4 , ya que f(5) devuelve una función que es básicamente
def g(b): return 5 * bUno podría ahora hacer cosas como esta
mult_by_5 = f(5) [mult_by_5(x) for x in range(10)]Seamos elegantes, ¿qué pasa con más funciones anidadas?:
def f(a): def g(b): def h(c): return a * b *c return h return g f(2)(3)(4) # 24