87 votes

Tuple de Python décompressant dans l'instruction de retour

Le langage Python (surtout les 3.x) permet de très générales déballage de iterables, un exemple simple de ce qui est

a, *rest = 1, 2, 3

Au fil des ans, ce déballage a été progressivement généralisée (voir, par exemple, PEP 3132 et PEP 448), lui permettant d'être utilisé dans de plus en plus de circonstances. Ainsi, j'ai été surpris de découvrir que le suivant n'est pas valide la syntaxe de Python 3.6 (et le reste en Python 3.7):

def f():
    rest = [2, 3]
    return 1, *rest  # Invalid

Je peux le faire fonctionner en encapsulant le retour de tuple, entre parenthèses, comme ceci:

def f():
    rest = [2, 3]
    return (1, *rest)  # Valid

Le fait que je l'utilise dans un return déclaration semble être important, comme

t = 1, *rest

est en effet juridique et les résultats dans le même avec ou sans parenthèses.

Ont ce cas simplement été oublié par les développeurs Python, ou il y a aucune raison pour que ce cas n'est pas valide la syntaxe?

Pourquoi j'ai des soins

Cela rompt un contrat important, je pensais que j'avais avec le langage Python. Considérez les points suivants (valable aussi) solution:

def f():
    rest = [2, 3]
    t = 1, *rest
    return t

Normalement, quand j'ai ce code, je considère t être un nom temporaire, qui je devrais être en mesure de se débarrasser de tout simplement remplacer t dans le bas de la ligne avec sa définition. Dans ce cas cependant, ce qui conduit au code non valide

def f():
    rest = [2, 3]
    return 1, *rest

Bien sûr, c'est pas une grosse affaire pour avoir à la place des parenthèses autour de la valeur de retour, mais généralement de nouvelles parenthèses ne sont nécessaires pour distinguer entre plusieurs résultats possibles (regroupement). Ici ce n'est pas le cas, comme en laissant de côté les parenthèses ne produit pas certains autres un comportement indésirable, mais plutôt pas de comportement à tous.

44voto

David Cuthbert Points 588

Je suppose que c'est un accident, sur la base des commentaires de ce commit pour Python 3.2.

Que l'activation de la validation de l'expression d'affectation de prendre un testlist_star_expr de la production (ce qui permet sans parenthèse déballage), mais à gauche de l'instruction de retour de prendre un testlist de la production. Je soupçonne que la validation a juste manqué ce (et éventuellement d'autres endroits, mais je me concentre sur l' return_stmt de la production pour l'instant).

Je suis allé de l'avant et modifié le Python de Grammaire/Grammaire fichier pour permettre cela. Tous les tests de continuer à passer, y compris ceux de l' test_grammar.py le fichier (mais cela ne semble pas terriblement exhaustive).

Si vous êtes curieux, c'est le changement que j'ai fait. Se sentir libre de clone ou de télécharger ma fourchette.

Mise à JOUR: j'ai envoyé un bpo question et un pull request pour le retour (et le rendement) déballage.

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