Pourquoi Python cession de ne pas renvoyer une valeur?
Pourquoi Python affectation d'une déclaration plutôt qu'une expression? Si c'était une expression qui renvoie la valeur de la droite, à l'affectation, elle aurait permis de beaucoup moins verbeux code dans certains cas. Est-ce que je ne peux pas voir?
Par exemple:
# lst is some sequence
# X is come class
x = X()
lst.append(x)
aurait pu être réécrit comme suit:
lst.append(x = X())
Bien, pour être précis, le ci-dessus ne fonctionnera pas parce que x
serait traitée comme un argument mot-clé. Mais une autre paire de parenthèses (ou un autre symbole pour le mot-clé arguments) aurait résolu que.
- Quel est votre exemple de code ont à voir avec la question?
- mon erreur. La version éditée (@Laurence Gonsalves) est bonne.
- "Y at-il des questions que je ne peux pas voir?" Il semble que "beaucoup moins verbeux code" est de toute façon pas un problème. Laconique, cryptique code de golf semble être un problème. Êtes-vous d'actualisation que l'on a pour une raison quelconque?
- Lott: je suppose que je pensais de simples exemples, comme celui que j'ai donné, je n'en vois pas trop cryptique); je suis d'accord que la capacité de l'abus de ce qui pourrait être l'une des raisons à l'encontre de cette fonctionnalité.
- J'aime cette question et d'autres questions comme ça. Je crois que les réponses et les commentaires sont très constructifs et utiles. Je suis juste étonné de la fermeture de la police n'a pas l'arrêter, déjà NC 😉
- J'ai demandé ça il y a longtemps, avant que j'ai appris que SI la communauté fronce les sourcils sur de telles questions. Je pense que j'ai juste eu de la chance avec celui-ci; semblables questions que j'ai posées plus tard, ont été fermés 🙂
- Le seul (et je pense de plus en plus évidents) cas de cession n'est pas l'expression qui me gêne pas de fin à chaque fois: ligne = curseur.fetchone() \ tandis que la ligne: \ ... \ row = curseur.fetchone(), au lieu de tout le rang = curseur.fetchone(): Peut-être l'ajouter à la question?
lst.append(X())
aussi fonctionne parfaitement bien- Je voulais avoir
X()
assignée à la variablex
; et aussi avoir le mêmeX()
ajouté à la liste.
Vous devez vous connecter pour publier un commentaire.
Il y a beaucoup qui pensent que le fait d'avoir des affectations être des expressions, en particulier dans des langages comme Python où tout valeur est admissible dans un état (pas seulement les valeurs d'un type booléen), est sujette à erreur. Sans doute Guido est/était parmi ceux qui se sentent de cette façon. L'erreur classique est:
La situation est un peu plus compliqué en Python que c'est dans un langage comme le C, car en Python à la première affectation à une variable est également sa déclaration. Par exemple:
Dans ces deux fonctions de la "
print x
" lignes de faire des choses différentes: l'une fait référence à la variable globalex
, et l'autre se réfère à la variable localex
. Lex
dansg
est locale en raison de la cession. Cela pourrait être encore plus à confusion (que c'est déjà le cas) si il était possible d'enterrer la mission à l'intérieur d'une plus grande expression ou de la déclaration.assert (0, "foo")
avec des avertissements activé (python -Wd).import
états sont placés à l'intérieurif
conditions 🙂import
s sont fait de façon dynamique, et c'est considéré comme une caractéristique. Voir le code Python pour leos
bibliothèque et comment elle met en œuvreos.path
par l'importation de différents modules en fonction de l'architecture du système. Je pense que Lennart point finalement devenu clair dans son dernier commentaire.python -m py_compile xyz.py
pour chaquexyz.py
dans le projet (il y a même un utilitaire intégrécompileall
pour aider avec ça). Mais ensuite j'ai lu @Lennart Regebro commentaire: Donc, si il y avait un fonctionnaire pysyntax vérificateur de vous exécuter, puis, de l'OMI, vous avez un bon argument. j'en conclus que le compilateur intégré n'est pas assez puissant pour attraper le non intentionnels de l'utilisation de=
au lieu de==
.==
vs=
fautes de frappe, car elle n'a pas au moment de la compilation vérification de la syntaxe. Je pense que si l'on voulait vraiment le faire, il pourrait fonctionner, aussi longtemps que l'on a ajouté un plus puissant vérificateur de syntaxe (bien sûr, également en supposant que les développeurs pourront utiliser que pour vérifier les mises en garde avant l'expédition de leurs produits).a=b=4
est permis et fonctionne comme prévu.Le monde réel de la réponse: il n'est pas nécessaire.
La plupart des cas, vous voyez ce en C sont en raison du fait que la gestion des erreurs est fait à la main:
De même pour la façon dont beaucoup de boucles écrit:
Ces cas de figures sont faites différemment en Python. Erreur de manipulation utilise généralement la gestion des exceptions; boucles généralement utiliser des itérateurs.
Les arguments contre il ne sont pas nécessairement de fracassant, mais ils sont pesés contre le fait qu'il n'est tout simplement pas important en Python.
while (x[k] += 1) <= limit: ...
; vous pouvez réécrire sans l'affectation comme une expression, mais qui requiert un non-trivial de restructuration.Cession (sous-)les expressions
(x := y)
sont pris en charge depuis le Python 3.8 (sorti Oct. 2019), donc en effet, vous pouvez maintenant reprendre ton exemple commelst.append(x := X())
.La proposition, PEP 572, a été officiellement acceptée par Guido en juillet 2018. Il y a eu aussi des propositions antérieures pour l'affectation des expressions, telles que le retrait de l' PEP 379.
Rappeler que jusqu'à la version 3,
print
était aussi un constat plutôt qu'une expression.La déclaration
x = y = z
d'attribuer la même valeur à plusieurs cibles (ou plutôt, plusieurs cible-listes, depuis le déballage est également autorisée) était déjà pris en charge (par exemple, depuis la version 1), mais est mis en œuvre comme un spécial la syntaxe plutôt que par chaînage successives d'attribution de sous-expressions. En effet, l'ordre dans lequel les différentes missions sont effectuées est inversé: la imbriqués les morses(x := (y := z))
doit attribuer ày
avantx
, alors quex = y = z
attribue àx
avanty
(qui peut être pertinente si vous définissez/affecter les indices ou les attributs d'une classe qui a été surchargé pour créer certains effets secondaires).(a*2 for a in b if a)
et d'autres composés de travail. L'intégralité dea = b = 3
est un instruction d'affectation, pas deux expressions comme dansa = (b:=3)
. Comparer avec les conteneur des littéraux, qui sont aussi de l'arbitraire à la taille de l'élément -(a, b, 3)
n'est pas le même que(a, (b, 3))
.Je crois que c'était un acte délibéré sur Guido de la partie, afin de prévenir certains classiques des erreurs. E. g.
if x = 3: print x
lorsque vous avez réellement voulu dire
if x == 3: ...
Je suis d'accord il y a des fois, j'ai voulu mais j'ai aussi manquer
{
et}
autour d'un bloc de code, et qui n'est pas près de changer.Si assignations ont été expressions, ces et beaucoup d'autres fonctionnalités devraient être retravaillées. Pour moi, c'est comme une affaire que vous avez à faire afin d'avoir un tel code lisible et fonctionnalités utiles.
Afin d'avoir
plutôt que
[ne parle pas de la classique (si a = b:) le type d'erreur.]
D'entrer dans le goût de la discussion, ou toute discussion perçue comme telle, est généralement une perte de temps, n'importe comment bon les arguments.
En dehors des principes plus généraux, mon préféré de la raison pratique de disposer d'affectation être une expression est d'avoir un lisible équivalent d'une instruction du cas, quand je veux correspondre à une chaîne avec plusieurs modèles (extraction des sous-modèles), jusqu'à ce que l'on y réussit. Peut-être quelqu'un a une solution sympa qui je n'ai pas vu.
De toute façon ... pourquoi ne pas faire plaisir à tout le monde en faisant deux mondes par le biais d'un interprétables commentaire au début du fichier de module qui stipule explicitement que les affectations peut être utilisé comme expression, si le programmeur désire?
Des gens satisfaits de la situation actuelle ne verrez pas de changement, et auront toujours leurs erreurs de syntaxe détecté de la même manière.
Et les gens qui veulent l'utiliser à l'affectation des expressions aurez simplement à dire.
Je ne vois pas en permettant de l'utiliser à des affectations dans des expressions dans un programme existant qui n'a pas l'utiliser (en ajoutant simplement le suggère le commentaire ci-dessus) serait de changer la sémantique du programme.
La paix.
Post-sriptum -
C'est ajouté, après les cinq premiers alinéas de l'article 1 dans la discussion ci-dessous ont été publiés.
Je ne sais pas pourquoi Python concepteurs fait ce choix. L'évitement de l'
certes d'erreur courants
if a=b : ...
au lieu deif a==b : ...
està peine une justification.
Tout d'abord, il pourrait très facilement être évité avec une autre notation pour
d'affectation, tels que
:=
ou<-
, plus approprié étant donné que l'affectationn'est pas symétrique, et utilisé dans certains des premiers ancêtres de Python.
Deuxième, le même problème est toléré dans un autre contexte. On peut
écrire
a = b=c
tout sens réellement à écrirea = b==c
qui esttout à fait différent. Et l'erreur n'est pas visible lorsque
b
etc
sont des expressions de grande taille. En outre, alors qu'il serait probablement
détecté comme un type d'erreur si le langage statiquement typé, ce
n'est pas si typées dynamiquement langage comme Python (c'est
vrai de
=
contre==
dans tous les contextes).Cette tolérance est d'autant plus surprenant que l'affectation multiple de
la forme
a = b = c
est à peine une caractéristique essentielle de la langue,à peine une fonctionnalité très utile.
Tout cela ressemble à des restes de début de la conception décisions, certains motivés
par des similitudes avec d'autres langages comme C ou Bash parce que Python
est également un langage de script, mais il est devenu beaucoup plus que cela. Dans
d'autres termes, il semble de plus accidentelle que bien pensé de la conception.
J'espère que c'est pas ce que les gens ont à l'esprit quand on parle de
pythonicity.
Ceci étant dit, celles-ci sont mineures syntaxique restrictions, cependant ennuyeux.
Le langage semble bien mieux conçu dans l'ensemble (avec une certaine restriction mentale
concernant le champ d'application des règles, jusqu'à ce que j'ai fait mon esprit à propos de sa logique).
Un aspect intéressant de cette discussion est que l'interdiction de
affectation en tant qu'expression (bien qu'il pourrait être résolu par une notation
le changement) est également rendue nécessaire par l'absence de typage statique.
Mais il est à prévoir que l'absence de typage statique, qui est un
conception légitime choix, fait beaucoup de bugs plus difficiles à attraper. C'est
un très constat général. Néanmoins, c'est le choix fait par
Python concepteurs. Ainsi soit-il.
Mais ensuite, ils ne peuvent guère regretter que la confusion entre l'égalité et l'
la cession sera plus difficile de les attraper. C'est seulement une conséquence directe,
une des nombreuses conséquences de leurs choix de conception de plus de flexibilité au
la charge de la détection d'erreur. Afin de détection d'erreur est une mauvaise excuse
pour cette limitation lors de l'affectation.
Concernant le fait que l'expression d'une assignation mélange fonctionnel
et de l'impératif de style, c'est un non-problème. Le mélange est déjà
partout dans la langue.
Est-il une justification écrite en Python que le document sur les choix de conception en général, et le problème abordé ici en particulier ?