Comment utiliser les opérateurs de pré-incrémentation/décrémentation (++
, --
), tout comme en C++ ?
Pourquoi ++count
s'exécute-t-il, mais ne modifie pas la valeur de la variable ?
Comment utiliser les opérateurs de pré-incrémentation/décrémentation (++
, --
), tout comme en C++ ?
Pourquoi ++count
s'exécute-t-il, mais ne modifie pas la valeur de la variable ?
++
n'est pas un opérateur. C'est deux opérateurs +
. L'opérateur +
est l'opérateur d'identité, qui ne fait rien. (Clarification : les opérateurs unaires +
et -
ne fonctionnent que sur les nombres, mais je présume que vous ne vous attendriez pas à ce qu'un éventuel opérateur ++
fonctionne sur les chaînes de caractères.)
++count
Se traduit par
+(+count)
Ce qui se traduit par
count
Vous devez utiliser l'opérateur légèrement plus long +=
pour faire ce que vous voulez faire :
count += 1
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 de Guido van Rossum pour cette décision, mais je peux imaginer quelques arguments :
++count
est ambiguë, car cela pourrait être +
, +
, count
(deux opérateurs +
unaires) tout aussi bien que ce pourrait être ++
, count
(un opérateur unaire ++
). Ce n'est pas une ambiguïté syntaxique significative, mais elle existe.++
n'est rien de plus qu'un synonyme de += 1
. C'était une abréviation inventée parce que les compilateurs C étaient stupides et ne savaient pas comment optimiser a += 1
en l'instruction inc
que la plupart des ordinateurs possèdent. De nos jours, avec les compilateurs optimiseurs et les langages interprétés en bytecode, l'ajout d'opérateurs à un langage 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.++
est de confondre les différences (à la fois de priorité et de valeur de retour) entre les opérateurs d'incrémentation/décrémentation préfixes et postfixes, et Python aime éliminer les "pièges" du langage. Les problèmes de priorité des pré-/post-incrémentation en C sont assez complexes et très faciles à rater.
"L'opérateur + est l'opérateur « identité », qui ne fait rien." Seulement pour les types numériques ; pour les autres types, c'est une erreur par défaut.
D'accord. Mais encore une fois, ++
et --
ne devraient fonctionner que sur les types numériques.
Aussi, sachez que, en Python, += et ses équivalents ne sont pas des opérateurs pouvant être utilisés dans les expressions. En Python, ils sont plutôt définis comme faisant partie d'une "instruction d'assignation augmentée". Cela est cohérent avec la décision de conception du langage en Python de ne pas autoriser l'assignation ("=") en tant qu'opérateur au sein d'expressions arbitraires, contrairement à ce qui est possible en C. Voir docs.python.org/reference/…
Python n'a pas d'opérateurs d'incrémentation pré et post.
En Python, les entiers sont immuables. C'est-à-dire que vous ne pouvez pas les modifier. Cela est dû au fait que les objets entiers peuvent être utilisés sous plusieurs noms. Essayez ceci :
>>> b = 5
>>> a = 5
>>> id(a)
162334512
>>> id(b)
162334512
>>> a is b
True
Les variables a et b ci-dessus sont en fait le même objet. Si vous incrémentiez a, vous incrémenteriez aussi b. Ce n'est pas ce que vous voulez. Vous devez donc réaffecter. Comme ceci :
b = b + 1
Beaucoup de programmeurs en C qui ont utilisé Python ont voulu un opérateur d'incrémentation, mais cet opérateur aurait l'aspect d'incrémenter l'objet, alors qu'en réalité il le réaffecte. C'est pourquoi les opérateurs -=
et +=
ont été ajoutés, pour être plus courts que b = b + 1
, tout en étant plus clairs et plus flexibles que b++
, donc la plupart des gens vont incrémenter avec :
b += 1
Ce qui réaffectera b
à b+1
. Ce n'est pas un opérateur d'incrémentation, car il n'incrémente pas b
, il le réaffecte.
En résumé : Python se comporte différemment ici, car ce n'est pas du C, et ce n'est pas une enveloppe 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 en C, où vous les utilisez à chaque fois que vous avez une boucle, par exemple.
Cet exemple est faux (et vous confondez probablement l'immuabilité avec l'identité) - ils ont le même id en raison d'une optimisation du VM qui utilise les mêmes objets pour les nombres jusqu'à 255 (ou quelque chose comme ça). Par exemple (des nombres plus grands):
>>> a = 1231231231231
>>> b = 1231231231231
>>> id(a), id(b)
(32171144, 32171168)
L'allégation d'immuabilité est fallacieuse. Conceptuellement, i++
signifierait assigner i + 1
à la variable i
. i = 5; i++
signifie assigner 6
à i
, et non modifier l'objet int
pointé par i
. Autrement dit, cela ne signifie pas incrémenter la valeur de 5
!
@Escargot mécanique : Dans ce cas, il ne s'agirait pas du tout d'opérateurs d'incrémentation. Et puis l'opérateur += est plus clair, plus explicite, plus flexible et fait de toute façon la même chose.
Alors que les autres réponses sont correctes en ce sens qu'elles montrent ce que signifie habituellement un simple +
(à savoir, laisser le nombre tel quel, s'il s'agit d'un nombre), elles sont incomplètes en ce sens qu'elles n'expliquent pas ce qui se passe.
Pour être exact, +x
évalue à x.__pos__()
et ++x
à x.__pos__().__pos__()
.
Je pourrais imaginer une structure de classe TRÈS étrange (Enfants, ne faites pas ça à la maison!) comme ceci :
class ValueKeeper(object):
def __init__(self, value): self.value = value
def __str__(self): return str(self.value)
class A(ValueKeeper):
def __pos__(self):
print('appel de A.__pos__')
return B(self.value - 3)
class B(ValueKeeper):
def __pos__(self):
print('appel de B.__pos__')
return A(self.value + 19)
x = A(430)
print(x, type(x))
print(+x, type(+x))
print(++x, type(++x))
print(+++x, type(+++x))
En Python, une distinction entre expressions et déclarations est rigoureusement appliquée, contrairement à des langages tels que Common Lisp, Scheme, ou Ruby.
Donc en introduisant de tels opérateurs, vous violeriez la distinction entre expression et déclaration.
Pour la même raison, vous ne pouvez pas écrire
if x = 0:
y = 1
comme vous le feriez dans d'autres langages où une telle distinction n'est pas conservée.
Intéressant, cette restriction sera levée dans la prochaine version de Python 3.8 avec la nouvelle syntaxe pour les expressions d'assignation (PEP-572 python.org/dev/peps/pep-0572). Nous pourrons écrire 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 (:=
)
Un commentaire plutôt qu'une réponse.
... mais je présume que vous ne vous attendriez pas à ce qu'un opérateur hypothétique
++
fonctionne sur des chaînes.)...
Dans au moins un langage, cela fonctionne.
perl -e '$a="ascf23"; print ++$a, "\n";'
ascf24
perl -e '$a="ascf29"; print ++$a, "\n";'
ascf30
perl -e '$a="ascfaa"; print ++$a, "\n";'
ascfab
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.
1 votes
Chris: Tu as répondu à ma question (le quoi). De plus, j'aimerais savoir pourquoi Python diffère dans ce comportement par rapport à C/C++.
24 votes
Python n'est pas C ou C++. Différentes décisions de conception ont été prises pour créer ce langage. En particulier, Python ne définit délibérément pas d'opérateurs d'attribution pouvant être utilisés dans une expression arbitraire; plutôt, il existe des instructions d'attribution et des instructions d'attribution augmentée. Voir la référence ci-dessous.
10 votes
Qu'est-ce qui vous a fait penser que python avait des opérateurs
++
et--
?39 votes
Kaizer: Venant de C/C++, j'écris ++count et cela compile en Python. J'ai donc pensé que le langage possède les opérateurs.
0 votes
Je crois que ++ existe en C principalement car c'est du sucre syntaxique pour l'arithmétique des pointeurs, par exemple le classique
while (dest++ = src++) {;}
.4 votes
Étant donné que la plupart des langages orientés objet contemporains utilisaient ces symboles lorsque GVR a créé Python, ne serait-il pas logique d'inclure un avertissement de syntaxe pour cette construction?
7 votes
@mehaase ++ et -- n'existent pas en c "comme un sucre syntaxique pour l'arithmétique des pointeurs", ils existent car de nombreux processeurs ont des mécanismes d'accès mémoire d'incrémentation et de décrémentation automatiques (en général l'indexation des pointeurs, l'indexation de la pile) faisant partie de leur jeu d'instructions natif. Par exemple, en assembleur 6809:
sta x++
... l'instruction atomique qui en résulte stocke l'accua
où lex
pointe, puis incrémentex
de la taille de l'accumulateur. Cela est fait car c'est plus rapide que l'arithmétique des pointeurs, car c'est très courant et parce que c'est facile à comprendre. Tant le pré- que le post-décrément.0 votes
@fyngyrz pour x86, il existe en réalité des instructions pour l'incrémentation et la décrémentation et c'est pourquoi (et comment C interprète)
++
et--
existent en C, ce n'est pas juste "du sucre syntaxique pour l'arithmétique des pointeurs".i++
eti += 1
ne sont pas la même chose. Vérifiez les instructions x86 inc et dec.0 votes
@christos-lytras - c'est à peu près exactement ce que j'ai dit. Vous répondez à la mauvaise personne.
0 votes
@christos-lytras - aussi - x++ --y, etc. long, long prédate l'ensemble d'instructions x86. Par exemple, le 6809 avait un ensemble impressionnant de modes d'indexation / de pile auto-inc et auto-dec ainsi que inc, dec, add, subtract et ainsi de suite.
0 votes
@fyngyrz oui, cela dépend toujours du compilateur et de l'ensemble d'instructions (assembleur, architecture du processeur) pour lequel il a été conçu. S'il ne dispose d'aucune instruction d'incrémentation, il utilisera les instructions d'addition. Les langages sont agnostiques en ce qui concerne la façon dont les compilateurs traduisent le code.
0 votes
Avez-vous essayé
+compter
,---compter
et+-+-+compter
? Ceux-ci "compilent" aussi, mais que sont-ils censés faire?