Python: orden de desempaquetado de valores en los parámetros del método

8
def fun(a, b, c, d):
    print('a:', a, 'b:', b, 'c:', c, 'd:', d)

por que este funciona

fun(3, 7, d=10, *(23,))

e imprime:

a: 3 b: 7 c: 23 d: 10

mientras esto

fun(3, 7, c=10, *(23,))

no

Traceback (most recent call last):
  File "/home/lookash/PycharmProjects/PythonLearning/learning.py", line 10, in <module>
    fun(3, 7, c=10, *(23,))
TypeError: fun() got multiple values for argument 'c'
Łukasz
fuente
No sé la razón exacta por la que se produce el error, pero nunca debe tener argumentos variables después de los argumentos de palabras clave. Normalmente se produce un error, pero el desempaquetado de tuplas parece arrojar un error diferente al normal SyntaxError: positional argument follows keyword argument.
Error - Remordimiento sintáctico
@ Error-SyntacticalRemorse. Creo que te estás perdiendo el punto. OP ha encontrado un caso en el que realmente puede poner un posicional después de una palabra clave, y funciona.
Físico loco
@MadPhysicist veo eso. Pero estaba más que simplemente haciendo una declaración de que el desempaquetado de tuplas no debería tener lugar después de los argumentos de palabras clave. Así lo hice como un comentario, no como una respuesta.
Error - Remordimiento sintáctico
1
Impresionante pregunta. Nunca supe que esto era una cosa.
Error - Remordimiento sintáctico

Respuestas:

6

Con *(23,), está desempacando los valores en la tupla (23,)como argumentos posicionales, siguiendo los argumentos posicionales que ya están definidos, a saber, 3for ay 7for b, por 23lo que se asignarían al parámetro c, por eso fun(3, 7, d=10, *(23,))funciona, pero fun(3, 7, c=10, *(23,))también está asignando un valor 10a cas un argumento de palabra clave, por lo que se considera un conflicto ya cque no se puede asignar con ambos 23y 10.

Tenga en cuenta que, si bien es legal, algunos desaconsejan desempaquetar argumentos iterables después de los argumentos de palabras clave, como se discute aquí , aunque la sintaxis finalmente se mantiene.

blhsing
fuente
Está claro lo que está sucediendo, pero ¿desde cuándo puede desempaquetar los posicionales después de las palabras clave?
Físico loco el
Desde Python 3.
blhsing
¿Tiene usted una fuente para eso? ¿Es intencional y documentado, o posiblemente un error / omisión?
Físico loco
El desempaquetado de tuplas debe tener lugar antes de los argumentos de palabras clave en términos de orden de operación. Podría ser una omisión ...
Error - Remordimiento sintáctico
1
@MadPhysicist Mi mal. Estaba pensando en otra cosa. Esta sintaxis también es legal en Python 2. El caso de uso principal, como se desprende del caso de prueba de CPython f(1,2,c=3,*d,**e)en test_ast.py , es permitir que una función de contenedor pase argumentos variables y argumentos de palabras clave a la función envuelta de una manera más intuitiva, colocando tanto los argumentos variables como las palabras clave variables argumentos al final de la lista de argumentos.
blhsing