Je remarque qu'un opérateur de pré-incrémentation / décrémentation peut être appliqué sur une variable (comme ++count
). Il compile, mais il ne change pas réellement la valeur de la variable!
Quel est le comportement des opérateurs de pré-incrémentation / décrémentation (++ / -) en Python?
Pourquoi Python s'écarte du comportement de ces opérateurs vu en C / C ++?
++
et les--
opérateurs?sta x++
... l'instruction atomique qui en résulte stocke l'a
accumulateur où ilx
pointe, puis incrémentex
de la taille de l'accumulateur. Cela est dû au fait qu'il est plus rapide que l'arithmétique des pointeurs, parce qu'il est très courant et qu'il est facile à comprendre. Pré et post.Réponses:
++
n'est pas un opérateur. Il s'agit de deux+
opérateurs. L'+
opérateur est l' opérateur d' identité , qui ne fait rien. (Clarification: les opérateurs unary+
et-
ne fonctionnent que sur les nombres, mais je suppose que vous ne vous attendriez pas à ce qu'un++
opérateur hypothétique travaille sur les chaînes.)Analyse comme
Ce qui se traduit par
Vous devez utiliser l'
+=
opérateur légèrement plus long pour faire ce que vous voulez faire:Je soupçonne que les opérateurs
++
et--
ont été omis pour des raisons de cohérence et de simplicité. Je ne connais pas l'argument exact que Guido van Rossum a avancé pour la décision, mais je peux imaginer quelques arguments:++count
est ambiguë, car elle pourrait être+
,+
,count
(deux unaire+
opérateurs) tout aussi facilement qu'il pourrait l' être++
,count
(un unaire++
opérateur). Ce n'est pas une ambiguïté syntaxique significative, mais elle existe.++
n'est rien de plus qu'un synonyme de+= 1
. C'était un raccourci inventé parce que les compilateurs C étaient stupides et ne savaient pas comment optimisera += 1
lesinc
instructions de la plupart des ordinateurs. En cette journée d'optimisation des compilateurs et des langages interprétés par bytecode, l'ajout d'opérateurs à un langage pour permettre aux programmeurs d'optimiser leur code est généralement mal vu, en particulier dans un langage comme Python conçu pour être cohérent et lisible.++
opérateurs consiste à mélanger les différences (à la fois en priorité et en valeur de retour) entre les opérateurs pré et post-incrémentation / décrémentation, et Python aime éliminer les "gotcha" -s de langue. Les problèmes de priorité de pré / post-incrémentation en C sont assez velus et incroyablement faciles à gâcher.la source
+
opérateur unaire a une utilité. Pour les objets decimal.Decimal, il arrondit à la précision actuelle.+ +
et++
sans casser LL (1).++
n'est rien de plus qu'un synonyme de+= 1
. Il existe des variantes pré-incrémentation et post-incrémentation de ++ donc ce n'est clairement pas la même chose. Je suis cependant d'accord avec le reste de vos points.Lorsque vous souhaitez incrémenter ou décrémenter, vous voulez généralement le faire sur un entier. Ainsi:
Mais en Python, les entiers sont immuables . C'est que vous ne pouvez pas les changer. En effet, les objets entiers peuvent être utilisés sous plusieurs noms. Essaye ça:
a et b ci-dessus sont en fait le même objet. Si vous incrémentiez a, vous incrémenteriez également b. Ce n'est pas ce que tu veux. Vous devez donc réaffecter. Comme ça:
Ou plus simple:
Qui sera réaffecté
b
àb+1
. Ce n'est pas un opérateur d'incrémentation, car il n'incrémente pasb
, il le réaffecte.En bref: Python se comporte différemment ici, car ce n'est pas C et ce n'est pas un wrapper de bas niveau autour du code machine, mais un langage dynamique de haut niveau, où les incréments n'ont pas de sens et ne sont pas aussi nécessaires que dans C , où vous les utilisez chaque fois que vous avez une boucle, par exemple.
la source
i++
cela signifierait attribueri + 1
à la variablei
.i = 5; i++
signifie assigner6
ài
, et non modifier l'int
objet pointé pari
. Autrement dit, cela ne signifie pas d' augmenter la valeur de5
!i++
ne fonctionne que sur lvalues. S'il était prévu d'incrémenter l'objet pointé pari
, cette restriction serait inutile.Alors que les autres réponses sont correctes dans la mesure où elles montrent ce qu'est
+
habituellement (à savoir, laisser le numéro tel quel, s'il est un), elles sont incomplètes dans la mesure où elles n'expliquent pas ce qui se passe.Pour être exact,
+x
évalue versx.__pos__()
et++x
versx.__pos__().__pos__()
.Je pourrais imaginer une structure de classe TRÈS bizarre (les enfants, ne faites pas ça à la maison!) Comme ceci:
la source
Python n'a pas ces opérateurs, mais si vous en avez vraiment besoin, vous pouvez écrire une fonction ayant les mêmes fonctionnalités.
Usage:
A l'intérieur d'une fonction, vous devez ajouter locals () comme second argument si vous voulez changer la variable locale, sinon elle essaiera de changer global.
Avec ces fonctions, vous pouvez également:
Mais à mon avis, l'approche suivante est beaucoup plus claire:
Opérateurs de décrémentation:
J'ai utilisé ces fonctions dans mon module traduisant javascript en python.
la source
Wikipédia
Ainsi, en introduisant de tels opérateurs, vous briseriez la séparation expression / instruction.
Pour la même raison, vous ne pouvez pas écrire
comme vous pouvez dans certaines autres langues où cette distinction n'est pas préservée.
la source
if (n := len(a)) > 10: y = n + 1
par exemple. Notez que la distinction est claire en raison de l'introduction d'un nouvel opérateur à cet effet (:=
)TL; DR
Python n'a pas d'opérateurs unaires d'incrémentation / décrémentation (
--
/++
). Au lieu de cela, pour incrémenter une valeur, utilisezPlus de détails et gotchas
Mais faites attention ici. Si vous venez de C, même cela est différent en python. Python n'a pas de "variables" dans le sens où C le fait, à la place python utilise des noms et des objets , et en python
int
s sont immuables.alors disons que vous le faites
En python, cela signifie: créer un objet de type
int
ayant une valeur1
et lui lier le noma
. L' objet est une instance deint
valeur1
et le nom ya
fait référence. Le noma
et l'objet auquel il se réfère sont distincts.Maintenant, disons que oui
Puisque les
int
s sont immuables, ce qui se passe ici est le suivant:a
fait référence (c'est unint
avec id0x559239eeb380
)0x559239eeb380
(c'est1
)int
objet avec une valeur2
(il a un identifiant d'objet0x559239eeb3a0
)a
à ce nouvel objeta
fait référence à l'objet0x559239eeb3a0
et l'objet d'origine (0x559239eeb380
) n'est plus référencé par le noma
. S'il n'y a aucun autre nom faisant référence à l'objet d'origine, il sera récupéré plus tard.Essayez vous-même:
la source
Ouais, j'ai aussi manqué la fonctionnalité ++ et -. Quelques millions de lignes de code c ont ancré ce genre de pensée dans ma vieille tête, et plutôt que de le combattre ... Voici une classe que j'ai bricolé qui implémente:
Voici:
Vous pouvez l'utiliser comme ceci:
... ayant déjà c, vous pouvez le faire ...
....ou juste...
... et pour la (ré) affectation en entier ...
... alors que cela maintiendra c comme compteur de type:
ÉDITER:
Et puis il y a ce petit comportement inattendu (et complètement indésirable) ,
... parce qu'à l'intérieur de ce tuple, getitem () n'est pas ce qui est utilisé, mais une référence à l'objet est passée à la fonction de formatage. Soupir. Donc:
... ou, plus verbalement, et explicitement ce que nous voulions réellement arriver, bien que contre-indiqué sous sa forme réelle par la verbosité (utiliser à la
c.v
place) ...la source
Il n'y a pas d'opérateurs post / pre increment / decrement en python comme dans des langages comme C.
Nous pouvons voir
++
ou--
comme plusieurs signes se multiplier, comme nous le faisons en mathématiques (-1) * (-1) = (+1).Par exemple
Analyse comme
Ce qui se traduit par
Parce que la multiplication du
-
signe par le-
signe est+
Et enfin,
la source
-----count
.Dans python 3.8+, vous pouvez faire:
Vous pouvez faire beaucoup de réflexion avec cela.
Ou si vous voulez écrire quelque chose avec une syntaxe plus sophistiquée (le but n'est pas l'optimisation):
Il retourne bien 0 si un dos n'existe pas sans erreurs, puis le mettra à 1
la source