tuples Semántica del desempaquetado de la tupla en python.





3 Answers

Sospecho que es por coherencia con la notación en estrella en las definiciones de funciones, que es, después de todo, el modelo para la notación en estrella en las llamadas a funciones.

En la siguiente definición, el parámetro *c absorberá todos los argumentos subsiguientes que no sean de palabras clave, por lo que, obviamente, cuando se llame a f , la única forma de pasar un valor para d será como un argumento de palabra clave.

def f(a, b, *c, d=1):
    print "slurped", len(c)

(Tales "parámetros de palabras clave solamente" solo se admiten en Python 3. En Python 2 no hay manera de asignar valores después de un argumento destacado, por lo que lo anterior es ilegal).

Por lo tanto, en una definición de función, el argumento destacado debe seguir todos los argumentos posicionales ordinarios. Lo que observaste es que la misma regla se ha extendido a las llamadas de función. De esta manera, la sintaxis en estrella es consistente para declaraciones de funciones y llamadas de funciones.

Otro paralelismo es que solo puede tener un argumento destacado (único) en una llamada a función. Lo siguiente es ilegal, aunque uno podría fácilmente imaginar que está permitido.

f(*(1,2), *(3,4))
python tuples iterable-unpacking

¿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?




Algunas observaciones:

  1. Python procesa los argumentos posicionales antes de los argumentos de palabras clave ( f(c=3, *(1, 2)) en su ejemplo, aún se imprime 1 2 3 ). Esto tiene sentido ya que (i) la mayoría de los argumentos en las llamadas a funciones son posicionales y (ii) la semántica de un lenguaje de programación debe ser inequívoca (es decir, la elección debe hacerse de cualquier manera en el orden en que se procesan los argumentos posicionales y de palabras clave) ).
  2. Si tuviéramos un argumento posicional a la derecha en una llamada de función, sería difícil definir lo que eso significa. Si llamamos f(*(1, 2), 3) , ¿debería ser f(1, 2, 3) o f(3, 1, 2) y por qué cualquier opción tendría más sentido que la otra?
  3. Para una explicación oficial, PEP 3102 proporciona mucha información sobre cómo funcionan las definiciones de funciones. La estrella (*) en una definición de función indica el final de los argumentos de posición (sección Especificación ). Para ver por qué, considere: def g(a, b, *c, d) . No hay forma de proporcionar un valor para d no sea como un argumento de palabra clave (los argumentos posicionales serían 'grabados' por c ).
  4. Es importante darse cuenta de lo que esto significa: cuando la estrella marca el final de los argumentos posicionales, eso significa que todos los argumentos posicionales deben estar en esa posición o a la izquierda de la misma.



Si tiene un parámetro de solo palabras clave de Python 3, como

def f(*a, b=1):
    ...

entonces puede esperar que algo como f(*(1, 2), 3) establezca a a (1 , 2) b a 3 , pero por supuesto, incluso si la sintaxis que desea está permitida, no lo haría, porque la palabra clave -Sólo los parámetros deben ser solo de palabra clave, como f(*(1, 2), b=3) . Si estuviera permitido, supongo que tendría que establecer a a (1, 2, 3) y dejar b como el valor predeterminado 1 . Entonces, tal vez no sea ambigüedad sintáctica sino ambigüedad en lo que se espera, que es algo que Python trata de evitar.




Related