Le comportement d'incrémentation et de décrémentation les opérateurs en Python
Je remarque qu'une pré-incrémentation/décrémentation de l'opérateur peut être appliqué sur une variable (comme ++count
). Il compile, mais il ne modifie pas la valeur de la variable!
Quel est le comportement de la pré-incrémentation/décrémentation les opérateurs (++/--) en Python?
Pourquoi Python s'écarter du comportement de ces opérateurs vu en C/C++?
- Chris: Vous avez répondu à ma requête (le quoi). En outre, je voudrais savoir pourquoi Python diffère de ce comportement à partir de C/C++.
- Python n'est pas en C ou C++. Différentes décisions de conception est allé dans la fabrication de la langue. En particulier, Python a choisi délibérément de ne pas définir l'affectation des opérateurs qui peuvent être utilisées dans une expression arbitraire; au contraire, il ya des instructions d'affectation et augmentée des instructions d'affectation. Voir la référence ci-dessous.
- Ce qui vous a fait penser python avait
++
et--
opérateurs? - Kaizer: en Venant du C/C++, j'écris ++compter et il compile en Python. Donc, je pensais que la langue a les opérateurs.
- Je crois que ++ existe dans C surtout parce que c'est du sucre syntaxique pour l'arithmétique des pointeurs, par exemple, le classique
while (dest++ = src++) {;}
. - étant donné que la plupart des contemporains de la programmation orientée objet des langues a ces symboles GVR venu avec Python, il ne serait pas judicieux d'inclure une syntaxe avertissement pour cette construction?
- Vous êtes en supposant un niveau de planification et d'organisation pas de preuves
- et -- n'existent pas en c "sucre syntaxique pour l'arithmétique des pointeurs", ils existent parce que de nombreux fabricants ont automatique d'incrémentation et de décrémentation de la mémoire des mécanismes d'accès (en général pointeur de l'indexation, la pile d'indexation) dans le cadre de leurs natif du jeu d'instructions. Par exemple, en assembleur 6809:
sta x++
...atomique de l'instruction que les résultats des magasins de laa
accumulateur oùx
est de pointage, puis incrémentex
par la taille de l'accumulateur. Ceci est fait parce qu'il est plus rapide que l'arithmétique des pointeurs, car il est très commun, et parce que c'est facile à comprendre. À la fois pré - et-post.
Vous devez vous connecter pour publier un commentaire.
++
n'est pas un opérateur. Il est deux+
opérateurs. Le+
l'opérateur est le identité de l'opérateur, qui ne fait rien. (Précision: le+
et-
opérateurs unaires seulement le travail sur les nombres, mais je présume que vous ne vous attendez pas à une hypothétique++
à l'opérateur de travailler sur des chaînes de caractères.)S'analyse comme
Qui se traduit par
Vous devez utiliser le légèrement plus
+=
opérateur de faire ce que vous voulez faire:Je soupçonne le
++
et--
opérateurs ont été laissés de côté pour des raisons de cohérence et de simplicité. Je ne sais pas l'argument exact Guido van Rossum a donné pour la décision, mais je peux imaginer quelques arguments:++count
est ambigu, car il pourrait être+
,+
,count
(deux unaire+
opérateurs), tout comme il pourrait être++
,count
(un unaire++
opérateur). Ce n'est pas une importante ambiguïté syntaxique, mais il existe.++
n'est rien de plus qu'un synonyme pour+= 1
. C'était une abréviation inventé parce que les compilateurs C sont stupides et ne savent pas comment optimisera += 1
dans leinc
enseignement la plupart des ordinateurs ont. En ce jour de l'optimisation des compilateurs et le bytecode des langages interprétés, l'ajout d'opérateurs à une langue pour permettre aux programmeurs d'optimiser leur code est généralement mal vu, surtout dans un langage comme Python qui est conçu pour être cohérent et lisible.++
opérateurs est de mélanger les différences (à la fois dans l'ordre de priorité et en valeur de retour) entre le pré - et post-incrémentation/décrémentation les opérateurs, et Python aime à éliminer de la langue "gotcha"-s. Le la priorité des questions de pré-/post-incrémentation dans C sont assez poilu, et incroyablement facile à gâcher.++
et--
ne doit être prévu pour fonctionner sur les types numériques.+
opérateur a une utilisation. Pour les décimales.Virgule des objets, il arrondit à la précision actuelle.+ +
et++
sans casser LL(1).++
opérateurs?" questions fermées comme des doublons, car cette réponse représente 4% de ma réputation.strip()
au lieu detrim()
comme toutes les autres langues, pas de commutateurs, certains OO fonctions et d'autres non (len(s)
ets.lower()
). Très frustrant et incohérent de la languelen()
, est qu'ils ont généralement une carte à une méthode de l'objet, vous permettant de remplacer ou de donner le pouvoir à l'intégrées pour l'un de vos propres classes --s.__len__()
dans ce cas.s.__len__()
est là quand vous en avez vraiment envie de le remplacer, mais caché ne pas encombrer la grande majorité des classes qui n'en ai pas besoin.__len__()
n'est pas vraiment privé, c'est seulement du public, mais appelé par indiretion et b), nous avons maintenant besoin de connaître toutes les méthodes qui font appel au privé des méthodes de l'objet pourrait ai juste eu unlength()
méthode qui pourrait être remplacé si vous le souhaitez.__len__()
n'est pas vraiment privé, mais on dirait que quand vous n'en avez pas besoin, et seulement quand vous en avez besoin. Lorsque vous introspecter un objet de méthodes utiles, de ne pas vous trouver une indéfinilength()
et une centaine d'autres pas défini des méthodes intégrées. Mais une fois que vous le faites, il est toujours là sous les couvertures. J'ai besoin d'un verre. 😉++
n'est rien de plus qu'un synonyme pour+= 1
. Il y a des pré-incrémentation et post-incrémentation variantes de ++ donc c'est clairement pas la même chose. Je suis d'accord avec le reste de vos points, cependant.:=
de l'opérateur.Quand vous voulez pour incrémenter ou décrémenter, vous souhaitez généralement de le faire que sur un nombre entier. Comme:
Mais en Python, les entiers sont immuable. C'est que vous ne pouvez pas les modifier. C'est parce que l'entier des objets peut être utilisé sous plusieurs noms. Essayez ceci:
a et b ci-dessus sont en fait le même objet. Si vous incrémentés d'une, vous aussi, vous incrément b. Ce n'est pas ce que vous voulez. Donc, vous avez à réaffecter. Comme ceci:
Ou plus simple:
Qui permettra de réaffecter
b
àb+1
. Ce n'est pas un opérateur d'incrémentation, parce qu'il ne s'incrémente pasb
, il réaffecte il.En bref: Python se comporte différemment ici, parce qu'il n'est pas C, et n'est pas un bas niveau wrapper autour de code machine, mais un haut niveau de langage dynamique, où incréments n'ont pas de sens, et aussi ne sont pas aussi nécessaire qu'en C, où que vous les utilisez chaque fois que vous avez une boucle, par exemple.
i++
reviendrait à attribueri + 1
à la variablei
.i = 5; i++
moyens pour attribuer6
ài
, de ne pas modifier leint
objet pointé pari
. C'est, il ne signifie pas pour incrémenter la valeur de5
!i++
fonctionne uniquement sur lvalues. S'il était prévu d'augmenter l'objet pointé pari
, cette restriction serait inutile.++
vs+= 1
.f
avec aucun des effets secondaires peut être appelé "incrémenter" sif(x) == x + 1
, tient toujours pour toutes les valeurs numériquesx
. Autres personnes clairement de ne pas le voir de cette façon, je vais garder à l'esprit dans l'avenir. +1 pour une réflexion réponse en tout cas. P. S. - Clojure de l'opérateur d'incrémentation est encore plus explicite que++
: il est(inc value)
.++a
pourrait en être faite par l'interprète pour avoir exactement le même effet quea = a+1
et onta
point à l'ID de 6. Je pense que le vrai problème réside dans le fait que + est un opérateur unaire et que ++un pourrait signifier soitincrement a
ou+(+a)
qui est indistiguishable pour le python de l'analyseur.a = a + 1
autres que de remplacer un objet par un autre objet?a
. Voir ma réponse ci-dessus.a = 1; b = a; a = a + 1;
ne veut pas dire que b est maintenant de 2. Il ne s'incrémente pasa
.++
être le même que+=1
. Rien de mal à cela?++
xyz au lieu d'incrémenter car il pointe maintenant vers un autre objet? Est-ce un problème?a++
? de quel usage? Sauver un couple de personnage pour un rarement utilisé opération?++
a été utilisé en lieu et place de+=1
a++
permettrait d'évaluer àa += 1
? (outre le fait que ce serait une deuxième façon de faire)+=1
ou++
modifie simplement la valeur d'une variable de points à, à être plus grand que ce qu'il pointe actuellement à. Ni l'opérateur modifie le valeur de ce qu'est une variable de points. Cette réponse n'a pas vraiment donner une bonne raison pour laquelle un++
opérateur n'a pas été ajoutés.Tandis que les autres réponses sont correctes, dans la mesure où ils montrent ce qu'un simple
+
fait habituellement (à savoir, laisser le numéro tel qu'il est, si c'en est un), elles sont incomplètes, dans la mesure où ils n'expliquent pas ce qui se passe.Pour être exact,
+x
évalue àx.__pos__()
et++x
àx.__pos__().__pos__()
.Je ne pouvais imaginer une TRÈS étrange structure de classe (les Enfants, ne faites pas cela à la maison!) comme ceci:
Python n'a pas de ces opérateurs, mais si vous avez vraiment besoin, vous pouvez écrire une fonction ayant la même fonctionnalité.
Utilisation:
L'intérieur d'une fonction, vous devez ajouter des locals() comme deuxième argument, si vous voulez changer de variable locale, sinon, il va essayer de changer mondiale.
Aussi avec ces fonctions, vous pouvez faire:
Mais à mon avis l'approche suivante est beaucoup plus claire:
Décrémentation les opérateurs:
J'ai utilisé ces fonctions dans mon module de traduction de javascript pour python.
Wikipédia
Par l'introduction de tels opérateurs, vous briserait l'expression ou la déclaration de split.
Pour la même raison, vous ne pouvez pas écrire
que vous pouvez dans certaines autres langues où cette distinction n'est pas conservé.
Ouais, j'ai raté ++ et -- fonctionnalité ainsi. Quelques millions de lignes de code c enracinée de ce genre de pensée dans ma vieille tête, et plutôt que de le combattre... Voici une classe que j'ai pavées qui met en œuvre:
Ici, c'est:
Vous pouvez l'utiliser comme ceci:
...ayant déjà c, vous pourriez le faire...
....ou tout simplement...
...et pour (ré)affectation en entier...
...tout cela maintiendra c type de compteur:
EDIT:
Et puis il y a ce peu d'inattendu (et à fond indésirables) le comportement,
...parce qu'à l'intérieur que tuple, getitem() n'est pas utilisé, à la place d'une référence à l'objet est passé à la mise en forme de la fonction. Soupir. Donc:
...ou, plus avec beaucoup de détails, et explicitement ce que nous voulions qu'il se passe, bien que contre-indiqué en forme par le niveau de verbosité (utiliser
c.v
à la place)...TL;DR
Python n'a pas unaire incrémentation/décrémentation les opérateurs (
--
/++
). Au lieu de cela, pour incrémenter une valeur, utiliserPlus de détails et de pièges
Mais être prudent ici. Si vous venez à partir de C, ce qui est différent en python. Python n'a pas de "variables" dans le sens que C ne, à la place python utilise noms et objets, et en python
int
s sont immuables.donc permet de dire que vous ne
Ce que cela signifie dans le langage python est: créer un objet de type
int
avoir de la valeur1
et de lier le noma
à elle. Le objet est une instance deint
avoir de la valeur1
, et la noma
se réfère à elle. Le noma
et l'objet auquel il se réfère sont distincts.Maintenant, disons que vous ne
Depuis
int
s sont immuables, ce qui se passe ici est comme suit:a
fait référence (c'est unint
avec l'id0x559239eeb380
)0x559239eeb380
(c'est1
)int
objet avec la valeur2
(il a id d'objet0x559239eeb3a0
)a
à ce nouvel objeta
se réfère à l'objet0x559239eeb3a0
et de l'objet d'origine (0x559239eeb380
) n'est plus référencé par le nom dea
. Si il n'y a pas d'autres noms se référant à l'objet d'origine, il sera déchets ramassés plus tard.Essayez-les vous-même: