468 votes

Pas de Multiligne Lambda en Python: Pourquoi pas?

J'ai entendu dire que multiligne lambdas ne peuvent pas être ajoutés en Python parce qu'ils serait en contradiction du point de vue syntaxique avec les autres éléments de la syntaxe des constructions en Python. Je pensais à ce sujet sur le bus aujourd'hui et réalisé que je ne pouvais pas penser à une seule Python construire que multiligne lambdas clash avec. Étant donné que je connais la langue assez bien, cela m'a surpris.

Maintenant, je suis sûr que Guido avait une raison pour ne pas multiligne lambdas dans la langue, mais par curiosité: c'est quoi une situation où, y compris une multiligne lambda d'être ambigu? Est ce que j'ai entendu dire vrai, ou est-il une autre raison que Python ne permet pas multiligne lambdas?

821voto

Eli Courtwright Points 53071

Guido van Rossum (l'inventeur de Python) répond à cette question exacte de lui-même dans un vieux post de blog.
Fondamentalement, il admet qu'il est théoriquement possible, mais que toute solution proposée serait de l'onu-Pythonic:

"Mais la complexité de toute solution proposée pour ce puzzle est immense, pour moi: il nécessite l'analyseur (ou plus précisément, le lexer) pour être en mesure de basculer entre le tiret-sensibles et de retrait insensible aux modes, en gardant une pile de précédents modes et niveau d'indentation. Techniquement, qui peuvent tous être résolus (il y a déjà un empilement de niveaux d'indentation qui pourraient être généralisées). Mais rien de cela n'enlève ai le sentiment que c'est tout un complexe de Rube Goldberg machine."

182voto

balpha Points 18387

Regardez les suivantes:

map(multilambda x:
      y=x+1
      return y
   , [1,2,3])

Est-ce un lambda de revenir (y, [1,2,3]) (donc la carte ne reçoit qu'un seul paramètre, ce qui entraîne une erreur)? Ou faut-il revenir y? Ou est-ce une erreur de syntaxe, car la virgule sur la ligne nouvelle est égaré? Comment Python savez ce que vous voulez?

À l'intérieur des parenthèses, l'indentation n'est pas question pour python, donc vous ne pouvez pas sans ambiguïté travailler avec multilines.

C'est juste un exemple simple, il y a probablement plus d'exemples.

82voto

Seth Kriticos Points 357

C'est généralement très moche (mais parfois, les solutions de rechange sont encore plus laids), une solution est de faire un croisillons expression:

lambda: (
    doFoo('abc'),
    doBar(123),
    doBaz())

Il n'accepte pas toutes les assignations bien que, de sorte que vous aurez à préparer les données à l'avance. L'endroit ou j'ai trouvé ce utile est le PySide wrapper, où vous aurez parfois de courts rappels. Écrit supplémentaires fonctions de membre serait encore plus laid. Normalement, vous n'aurez pas besoin de cela.

Exemple:

pushButtonShowDialog.clicked.connect(
    lambda: (
    field1.clear(),
    spinBox1.setValue(0),
    diag.show())

20voto

Anon Points 3418

Un couple de liens pertinents:

Pendant un moment, j'ai suivi le développement de l'Erea, qui a été initialement va avoir Python indentation en fonction de la syntaxe de Ruby blocs de trop, en plus d'Erlang. Mais, le concepteur de la plaie, donnant sur l'indentation de la sensibilité, et ce qu'il a écrit à propos de cette décision comprend une discussion sur les problèmes qu'il a couru avec indentation + multi-blocs de lignes, et une augmentation de l'appréciation qu'il a gagné pour Guido de problèmes de conception/décisions:

http://www.unlimitednovelty.com/2009/03/indentation-sensitivity-post-mortem.html

Aussi, voici une proposition intéressante pour style Ruby blocs en Python, j'ai couru partout où Guido postes une réponse w/o réellement la prise de vue vers le bas (je ne sais pas s'il y a eu ultérieure abattre, tout de même):

http://tav.espians.com/ruby-style-blocks-in-python.html

6voto

Wai Yip Tung Points 5013

Permettez-moi d'essayer de s'attaquer @bl'alpha analyse de problème. Je voudrais utiliser des parenthèses autour de la multiligne lamda. Si il n'y a pas de parenthèses, le lambda définition est gourmand. De sorte que le lambda dans

map(lambda x:
      y = x+1
      z = x-1
      y*z,
    [1,2,3]))

retourne une fonction qui retourne (y*z, [1,2,3])

Mais

map((lambda x:
      y = x+1
      z = x-1
      y*z)
    ,[1,2,3]))

moyens

map(func, [1,2,3])

où func est le multiligne lambda qui renvoient y*z. Cela fonctionne?

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