37 votes

[] = (), () = () et {} = () 'assignations'

J'ai été surpris de trouver ce qui suit, en Python 3, les deux premiers soulever rien:

>>> [] = ()
>>> () = ()
>>> {} = ()
  File "<stdin>", line 1
SyntaxError: can't assign to literal

En Python 2.7, seul le premier soulève rien:

>>> [] = ()
>>> () = ()
  File "<stdin>", line 1
SyntaxError: can't assign to ()
>>> {} = ()
  File "<stdin>", line 1
SyntaxError: can't assign to literal

Ce qui se passe ici? Pourquoi sont alors pas la levée des erreurs? Et pourquoi l' () = () sans doute d'être valide en Python 3?

*Remarquez, vous pouvez remplacer le côté droit avec tout vide itérable (par exemple, [] = set()- )), je viens de choisir un tuple vide pour l'illustration

28voto

Chris_Rands Points 15161

Selon Issue23275, ce sont essentiellement les caprices causant pas de préjudice réel, mais aussi pas d'utilité. Notez que [] = () ne modifie pas l' list littérale:

>>> [] = ()
>>> type([])
<class 'list'>

[] = x états fondamentalement affirmer qu' x est itératif et qu' x est vide (bien que personne ne vous recommandons de les utiliser de cette façon), par exemple

>>> [] = (1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> [] = (1,)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack

Comme Jean-Y des commentaires, il est préférable de penser en termes de [] = () comme non pas une commande mais une manière d'être compatible avec Python itérable déballage de la syntaxe.

Comme ArrowCase commentaires, cette syntaxe s'étend également à des missions multiples:

>>> a = [] = ()
>>> a
()

En regardant les Disponible bytecode de l'affectation multiple montre que ces opérations sont similaires à la normale itérable déballage de la syntaxe, à l'aide de l' UNPACK_SEQUENCE enseignement:

>>> dis.dis('a = [] = ()')
  1           0 BUILD_TUPLE              0
              2 DUP_TOP
              4 STORE_NAME               0 (a)
              6 UNPACK_SEQUENCE          0
              8 LOAD_CONST               0 (None)
             10 RETURN_VALUE
>>> dis.dis('[a, b] = (1, 2)')
  1           0 LOAD_CONST               3 ((1, 2))
              2 UNPACK_SEQUENCE          2
              4 STORE_NAME               0 (a)
              6 STORE_NAME               1 (b)
              8 LOAD_CONST               2 (None)
             10 RETURN_VALUE

La même Issue23275 états qu' () = () a été ajouté comme valide la syntaxe de Python 3 pour la concordance. Il a été décidé que la suppression d' [] = () de casser le code inutilement, car il ne cause pas de préjudice et s'adapte avec itérable déballage de la logique. {} = () est toujours valide car le déballage de la syntaxe n'a pas de sens dans ce contexte avec des accolades.

Dans le cas où quelqu'un se demande, une syntaxe comme celle - list() = () est tout simplement syntaxiquement invalide, parce que vous pouvez ne jamais céder à l'appel de la fonction.

26voto

glglgl Points 35668

Il existe un moyen d'affecter des variables à partir d'un itérable:

 >>> a, b = iter((1, 2))
>>> a
1
>>> b
2
>>> [c, d] = iter((4, 5))
>>> c
4
>>> d
5
 

Les assignations [] = … et () = … semblent en être des cas particuliers.

9voto

WolframH Points 2482

Le côté gauche d'une instruction d'affectation est pas une expression, c'est une liste des cibles. Bref résumé:

  • Si la liste des cibles est un identifiant, le nom est juste lié à la droite.
  • Si la liste des cibles est une séparation par virgule liste des cibles, le côté droit est déballé et l'déballé sont attribués aux éléments de la liste des cibles.
  • Une liste peut être mise entre parenthèses ou entre crochets. En particulier, qui permet de créer des vides listes cible, comme on le voit dans vos exemples.

C'est ce qui explique pourquoi [] et () sont valables que du côté gauche des devoirs: ils sont la cible valide les listes. Toutefois, {} n'est pas, comme il n'est pas une cible valide la liste.

Bien sûr, {} peut-être partie d'une cible, par exemple en tant que primaire d'un abonnement: {}[()] = 0 est valable python (mais complètement inutile, bien sûr).

7voto

user2357112 Points 37737

C'est la syntaxe pour décompresser à deux éléments itérable en deux affectation des cibles:

[x, y] = whatever

Cette généralise jusqu'à trois cibles ou plus, mais il a également généralise vers le bas:

[x] = whatever

déballe un élément itératif dans une tâche cible, et

[] = whatever

décompresse un zéro élément itératif en zéro affectation des cibles (qui n'a rien de si whatever est un zéro-élément itératif, et lève une exception si ce n'est pas).

() = whatever également décompresse un zéro élément itératif, mais {} = whatever non; il n'y a pas de déballage de syntaxe qui implique des accolades.

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