python tuplas - Semántica del desempaquetado de la tupla en python.




3 Answers

Estoy bastante seguro de que la razón por la que a las personas "naturalmente" no les gusta esto es porque hace que el significado de los argumentos posteriores sea ambiguo, dependiendo de la longitud de la serie interpolada:

def dangerbaby(a, b, *c):
    hug(a)
    kill(b) 

>>> dangerbaby('puppy', 'bug')
killed bug
>>> cuddles = ['puppy']
>>> dangerbaby(*cuddles, 'bug')
killed bug
>>> cuddles.append('kitten')
>>> dangerbaby(*cuddles, 'bug')
killed kitten

no se puede decir con solo mirar las dos últimas llamadas a dangerbaby cuál funciona como se esperaba y cuál mata a la gatita fluffykins.

Por supuesto, parte de esta incertidumbre también está presente cuando se interpola al final. pero la confusión está restringida a la secuencia interpolada, no afecta a otros argumentos, como el bug .

[Hice una búsqueda rápida para ver si podía encontrar algo oficial. Parece que el prefijo * para varags se introdujo en Python 0.9.8 . La sintaxis anterior se discute aquí y las reglas de cómo funcionó fueron bastante complejas. ya que la adición de argumentos adicionales "tenía que" ocurrir al final cuando no había un marcador *, parece que eso simplemente continuó. finalmente, se menciona aquí una larga discusión sobre listas de argumentos que no fue por correo electrónico.]

vacia lista

¿Por qué python solo permite que los argumentos con nombre sigan una expresión de desempaquetado de tuplas en una llamada de función?

>>> def f(a,b,c):
...     print a, b, c
... 
>>> f(*(1,2),3)
  File "<stdin>", line 1
SyntaxError: only named arguments may follow *expression

¿Es simplemente una elección estética, o hay casos en los que permitir esto llevaría a algunas ambigüedades?




En primer lugar, es simple proporcionar una interfaz muy similar utilizando una función de envoltura:

def applylast(func, arglist, *literalargs):
  return func(*(literalargs + arglist))

applylast(f, (1, 2), 3)  # equivalent to f(3, 1, 2)

En segundo lugar, mejorar el intérprete para que admita su sintaxis de forma nativa puede agregar sobrecarga a la actividad muy crítica de la aplicación de la función. Incluso si solo requiere unas cuantas instrucciones adicionales en el código compilado, debido al alto uso de esas rutinas, eso podría constituir una penalización de rendimiento inaceptable a cambio de una característica que no es muy frecuente en una biblioteca de usuarios.




cambiar el orden:

def f(c,a,b):
    print(a,b,c)
f(3,*(1,2))



Related

python tuples iterable-unpacking