Quelqu'un peut-il expliquer les raisons concrètes pour lesquelles BDFL a choisi de créer une ligne unique de Python lambdas?
C'est bon:
lambda x: x**x
Cela entraîne une erreur:
lambda x:
x**x
Je comprends que faire lambda multi-line "dérangerait" les règles d'indentation normales et nécessiterait l'ajout d'exceptions supplémentaires, mais est-ce que cela ne vaut pas les avantages?
Regardez JavaScript, par exemple. Comment peut-on vivre sans ces fonctions anonymes? Ils sont indispensables. Les pythonistes ne veulent-ils pas éviter d'avoir à nommer chaque fonction multiligne pour la passer en argument?
def
? Il a maintenant exactement la même structure visuelle.Réponses:
Guido van van Rossum a répondu lui-même:
http://www.artima.com/weblogs/viewpost.jsp?thread=147358
En gros, il dit que même si une solution est possible, elle n’est pas conforme à la réalité de Python.
la source
c'est parfaitement bien de faire un lambda multiligne en python: voir
la vraie limitation de lambda est le fait que lambda doit être une expression unique ; il ne peut pas contenir de mot clé (comme python2
print
oureturn
).GvR a choisi de le faire pour limiter la taille du lambda, car ils sont normalement utilisés comme paramètres. Si vous voulez une vraie fonction, utilisez
def
la source
def
. Pensez-y: vous avez vraiment besoin d'un appelable comme paramètre de votre fonction? Et les utilisateurs de cette fonction ne sont pas autorisés à transmettre votre appelable par défaut? Comment peuvent-ils le passer si vous ne le leur donnez pas?Je sais que c'est très vieux, mais en prenant ici comme référence.
Une alternative à l'utilisation de lambda pourrait être d'utiliser une
def
méthode non conventionnelle. Le but est de passerdef
à une fonction, ce qui ne peut être fait que dans un seul cas - un décorateur. Notez que cette implémentationdef result
ne crée pas de fonction, mais crée le résultatreduce()
qui finit par être undict
.Prise Shameless : Je fais beaucoup de cela ici .
Notez que les lambdas multi-instructions peuvent être utilisés, mais uniquement avec du code vraiment, vraiment moche. Cependant, ce qui est intéressant, c’est la manière dont la portée fonctionne avec cette implémentation (notez l’utilisation multiple de la
name
variable et l’observation de lamessage
variable.la source
Pirater ensemble un lambda à déclarations multiples n'est pas si mal que le dit pyrospade: nous pourrions composer un tas de fonctions monadiques en utilisant bind, comme dans Haskell, mais puisque nous sommes dans le monde impur de Python, nous pourrions aussi bien utiliser des effets secondaires pour obtenir la même chose.
Je couvre quelques façons de faire cela sur mon blog .
Par exemple, Python garantit d'évaluer les éléments d'un tuple dans l'ordre, afin que nous puissions utiliser un
,
peu comme un impératif;
. Nous pouvons remplacer de nombreuses déclarations, commeprint
, par des expressions, commesys.stdout.write
.Par conséquent, les éléments suivants sont équivalents:
Notez que j'ai ajouté un
None
à la fin et que je l'ai extrait à l'aide de[-1]
; cela définit explicitement la valeur de retour. Nous n’avons pas à le faire, mais sans cela, nous obtiendrions une(None, None, None)
valeur de retour géniale , qui pourrait nous intéresser ou non.Nous pouvons donc séquencer les actions IO. Qu'en est-il des variables locales?
Python
=
forme une déclaration, nous devons donc trouver une expression équivalente. Une solution consiste à muter le contenu de la structure de données, passé en argument. Par exemple:Il y a peu de trucs utilisés dans
stateful_lambda
:*_
argument permet à notre lambda de prendre n'importe quel nombre d'arguments. Puisque cela ne permet aucun argument, nous récupérons la convention d'appel destateful_def
._
est juste une convention qui dit "je ne vais pas utiliser cette variable"lambda state: lambda *_: ...
(lambda state: ...)({})
state
à une valeur{}
sans utiliser une instruction d'affectation (par exemplestate = {}
) .state
tant que noms de variables et valeurs liéesstate.setdefault(a, b)
au lieu dea = b
etstate.get(a)
au lieu dea
[-1]
pour extraire la dernière valeur, qui agit comme unereturn
déclarationBien sûr, cela est assez fastidieux, mais nous pouvons créer une API plus agréable avec des fonctions d'assistance:
la source
Si je pouvais contribuer, utilisez un disjoncteur:
N'oubliez pas la très belle chose que python est capable d'écrire sur les marqueurs, comme dans l'exemple:
Et le lambda est très puissant, mais il n’est pas destiné à la substitution d’une fonction entière, je veux dire que vous pourriez le pirater comme (exemple emprunté à un collègue ci-dessus):
Mais voulez-vous vraiment le faire comme ça? Il est généralement illisible au bout d’un certain temps, c’est comme aller au début de la corde en commençant par la fin non déchirée.
Les Lambdas sont des fonctions uniques, dans la carte, filtrent et réduisent les fonctions dans la programmation orientée fonctionnelle (entre autres). Par exemple, obtenir des valeurs de caractère de valeurs qui sont des entiers et divisibles par 2
Vous pouvez l'utiliser comme expression de fonction pour diviser la fonction complexe (ou plusieurs et plusieurs lambdas, et l'insérer dans un autre lambda:
mais Python prend en charge les expressions de fonction d'une autre manière: les -lets disent que vous avez une fonction appelée
superAwesomeFunction
et que cette fonction peut faire des choses super impressionnantes, vous pouvez l'affecter à une variable en ne l'appelant pas, comme ceci:Alors maintenant, lorsque vous appelez SAF, vous appelez superAwesomeFunction ou sa méthode. Si vous effectuez une recherche dans votre dossier Lib, vous constaterez que la plupart des
__builtin__
modules python sont écrits de cette façon. Ceci est fait parce que parfois vous aurez besoin de fonctions qui font une tâche spécifique qui n’est pas assez nécessaire pour être utilisable par l’utilisateur mais qui est nécessaire pour plusieurs fonctions. Donc vous avez le choix. Vous ne pouvez pas avoir 2 fonctions portant le nom "superAwesomeFunction", vous pouvez avoir "superAwesomeFunctionDoingBasicStuf" et "realSuperAwesomeFunction" et ne mettre que la variable "realSuperAwesomeFunction" dans la variable "superAwesomeFunction" et vous avez terminé.Vous pouvez trouver l'emplacement des modules importés en entrant dans console
importedModule.__file__
(exemple réelimport os;os.__file__
), puis suivez ce répertoire dans le fichier importsModule.py et ouvrez-le dans l'éditeur pour trouver comment vous pouvez maximiser vos propres "connaissances".J'espère que cela vous aidera, vous et d'autres collègues en difficulté, peut-être.
la source