it-swarm.com.de

Warum gibt es in Python keine ++ und - Operatoren?

Warum gibt es in Python keine ++- und ---Operatoren?

389
Leonid

Das liegt nicht daran, dass es keinen Sinn macht. Es ist absolut sinnvoll, "x ++" als "x + = 1 zu definieren, wobei die vorherige Bindung von x ausgewertet wird".

Wenn Sie den ursprünglichen Grund erfahren möchten, müssen Sie entweder die alten Python-Mailing-Listen durchgehen oder jemanden fragen, der dort war (z. B. Guido).

Einfaches Inkrementieren und Dekrementieren ist nicht so nötig wie in anderen Sprachen. Sie schreiben Dinge wie for(int i = 0; i < 10; ++i) nicht oft in Python. Stattdessen machst du Dinge wie for i in range(0, 10).

Da es fast nicht so oft benötigt wird, gibt es viel weniger Grund, ihm eine eigene spezielle Syntax zu geben. Wenn Sie inkrementieren müssen, ist += normalerweise in Ordnung.

Es ist keine Entscheidung, ob es sinnvoll ist oder ob es getan werden kann - es tut und kann. Es ist eine Frage, ob der Nutzen es wert ist, zur Kernsyntax der Sprache beizutragen. Denken Sie daran, dies sind vier Operatoren - postinc, postdec, preinc, predec, und jeder von ihnen müsste seine eigenen Klassenüberladungen haben; Sie müssen alle spezifiziert und getestet werden. es würde der Sprache Opcodes hinzufügen (was eine größere und daher langsamere VM - Engine impliziert); Jede Klasse, die ein logisches Inkrement unterstützt, muss sie implementieren (über += und -=).

Dies ist bei += und -= alles überflüssig, so dass ein Nettoverlust entstehen würde.

404
Glenn Maynard

Diese originelle Antwort, die ich geschrieben habe, ist ein Mythos aus der Folklore des Rechnens : Dennis Ritchie entlarvte sie als "historisch unmöglich", wie in den Briefen an die Redaktion von Mitteilungen der ACM Juli 2012 doi: 10.1145/2209249.2209251


Die C-Inkrementierungs-/Dekrementierungsoperatoren wurden zu einer Zeit erfunden, als der C-Compiler nicht sehr intelligent war und die Autoren in der Lage sein wollten, die direkte Absicht anzugeben, dass ein Maschinensprachenoperator verwendet werden sollte, der eine Handvoll Zyklen für einen Compiler sparte könnte ein tun

load memory
load 1
add
store memory

anstatt

inc memory 

und der PDP-11 unterstützte sogar "Autoincrement" - und "Autoincrement Deferred" -Anweisungen, die *++p bzw. *p++ entsprechen. Siehe Abschnitt 5.3 von das Handbuch wenn Sie schrecklich neugierig sind.

Da Compiler klug genug sind, um die in der Syntax von C enthaltenen allgemeinen Optimierungstricks zu handhaben, sind sie jetzt nur noch eine syntaktische Annehmlichkeit.

Python hat keine Tricks, um dem Assembler Absichten mitzuteilen, da es keine verwendet.

82
msw

Ich habe immer angenommen, dass es mit dieser Linie des Python-Zen zu tun hatte:

Es sollte einen - und vorzugsweise nur einen - offensichtlichen Weg geben, dies zu tun.

x ++ und x + = 1 machen genau dasselbe, also gibt es keinen Grund, beides zu haben. 

56
GSto

Natürlich könnte man sagen "Guido hat sich so entschieden", aber ich denke, die Frage betrifft wirklich die Gründe für diese Entscheidung. Ich denke es gibt mehrere Gründe:

  • Es mischt Aussagen und Ausdrücke, was keine gute Praxis ist. Siehe http://norvig.com/python-iaq.html
  • Im Allgemeinen werden die Benutzer dazu angehalten, weniger lesbaren Code zu schreiben
  • Zusätzliche Komplexität bei der Sprachimplementierung, die in Python nicht erforderlich ist, wie bereits erwähnt
36
EMP

Da in Python ganze Zahlen unveränderlich sind (int + + gibt tatsächlich ein anderes Objekt zurück).

Mit ++/- müssen Sie sich auch vor dem Nachinkrementieren/Dekrementieren Sorgen machen, und es ist nur ein weiterer Tastendruck erforderlich, um x+=1 zu schreiben. Mit anderen Worten, es vermeidet mögliche Verwechslungen auf Kosten eines sehr geringen Gewinns.

14
Nathan Davis

Klarheit!

In Python geht es viel um clearity, und wahrscheinlich wird kein Programmierer die Bedeutung von --a richtig erraten, es sei denn, er/sie hat eine Sprache mit diesem Konstrukt gelernt.

In Python geht es auch viel darum, Konstrukte zu vermeiden, die zu Fehlern führen, und die ++-Operatoren sind bekanntermaßen reichhaltige Fehlerquellen. Diese beiden Gründe reichen aus, um diese Operatoren nicht in Python zu haben.

Die Entscheidung, dass Python Einrückungen zum Markieren von Blöcken anstelle von syntaktischen Mitteln wie etwa einer Form von Anfangs- und Endeklammern oder einer obligatorischen Endmarkierung verwendet, basiert weitgehend auf den gleichen Überlegungen.

Zur Veranschaulichung, werfen Sie einen Blick auf die -Diskussion über die Einführung eines bedingten Operators (in C: cond ? resultif : resultelse) in Python 2005. __ Lesen Sie mindestens das erste Nachricht und das Entscheidung message dieses Diskussion (das zuvor mehrere Vorläufer zum selben Thema hatte).

Trivia: Das häufig erwähnte PEP ist der "Python Extension Proposal" PEP 308 . LC bedeutet Listenverständnis , GE bedeutet Generatorausdruck (und machen Sie sich keine Sorgen, wenn diese Sie verwirren, sie sind keine der wenigen komplizierten Stellen in Python).

12
Lutz Prechelt

Es wurde einfach so entworfen. Inkrement- und Dekrementoperatoren sind nur Verknüpfungen für x = x + 1. Python hat typischerweise eine Entwurfsstrategie eingeführt, die die Anzahl alternativer Mittel zur Durchführung einer Operation reduziert. Erweiterte Zuweisung ist die nächstliegende Sache, um Operatoren in Python zu erhöhen/zu dekrementieren, und sie wurden erst in Python 2.0 hinzugefügt.

9
Reed Copsey

Ich bin sehr neu in Python, aber ich vermute, der Grund liegt in der Betonung zwischen veränderlichen und unveränderlichen Objekten in der Sprache. Nun, ich weiß, dass x ++ leicht als x = x + 1 interpretiert werden kann, aber es sieht so aus, als würde man in-place ein Objekt erhöhen, das unveränderlich sein könnte.

Nur meine Vermutung/Gefühl/Ahnung.

8
mkoistinen

Ich verstehe, warum Python keinen ++-Operator hat: Wenn Sie dies in Python a=b=c=1 schreiben, erhalten Sie drei Variablen (Labels), die auf dasselbe Objekt zeigen (dessen Wert 1 ist). Sie können dies anhand der id-Funktion überprüfen, die eine Objektspeicheradresse zurückgibt:

In [19]: id(a)
Out[19]: 34019256

In [20]: id(b)
Out[20]: 34019256

In [21]: id(c)
Out[21]: 34019256

Alle drei Variablen (Labels) zeigen auf dasselbe Objekt. Jetzt inkrementieren Sie eine Variable und sehen Sie, wie sie sich auf Speicheradressen auswirkt:

In [22] a = a + 1

In [23]: id(a)
Out[23]: 34019232

In [24]: id(b)
Out[24]: 34019256

In [25]: id(c)
Out[25]: 34019256

Sie können sehen, dass die Variable a jetzt auf ein anderes Objekt als Variablen b und c verweist. Da Sie a = a + 1 verwendet haben, ist dies explizit eindeutig. Mit anderen Worten, Sie weisen der Beschriftung a ein völlig anderes Objekt zu. Stellen Sie sich vor, Sie könnten a++ schreiben, da dies darauf hindeutet, dass Sie der Variablen a kein neues Objekt zugewiesen haben, sondern das alte ratter inkrementieren. Alle diese Sachen sind IMHO für die Minimierung von Verwirrung. Zum besseren Verständnis sehen Sie, wie Python-Variablen funktionieren:

Warum kann eine Funktion in Python einige Argumente so ändern, wie sie vom Aufrufer wahrgenommen werden, andere jedoch nicht?

Ist Python Call-By-Value oder Call-By-Reference? Weder.

Wird Python nach Wert oder nach Referenz übergeben?

Wird Python als Referenz übergeben oder als Wert übergeben?

Python: Wie kann ich eine Variable als Referenz übergeben?

Python-Variablen und Speicherverwaltung verstehen

Emulieren eines Verhaltens mit Wert in Python

Python-Funktionen rufen nach Referenz auf

Code wie ein Pythonista: Idiomatischer Python

8
Wakan Tanka

Erstens wird Python nur indirekt von C beeinflusst; Es wird stark von ABC beeinflusst, wobei diese Operatoren anscheinend nicht hat . Es sollte also keine große Überraschung sein, sie in Python nicht zu finden.

Zweitens werden Inkrementierung und Dekrementierung bereits von += und -= unterstützt.

Drittens umfasst die vollständige Unterstützung für einen ++- und ---Operatorsatz normalerweise die Unterstützung sowohl der Präfix- als auch der Postfix-Version. In C und C++ kann dies zu allen Arten von "schönen" Konstrukten führen, die (für mich) gegen den Geist der Einfachheit und Geradlinigkeit zu sein scheinen, den Python umarmt.

Während zum Beispiel die C-Anweisung while(*t++ = *s++); einem erfahrenen Programmierer einfach und elegant erscheint, ist es für jemanden, der es lernt, alles andere als einfach. Fügen Sie eine Mischung aus Präfix- und Postfix-Inkrementen und Dekrementen hinzu, und sogar viele Profis müssen aufhören und ein wenig nachdenken.

4
wberry

Ich glaube, es stammt aus dem Python-Credo, dass "explizit besser ist als implizit".

4
Sepheus

Dies kann daran liegen, dass @GlennMaynard die Angelegenheit wie im Vergleich zu anderen Sprachen betrachtet, aber in Python machen Sie die Dinge auf die Python-Art. Es ist keine Warum-Frage. Es ist da und Sie können Dinge mit x+= genauso machen. In The Zen of Python wird angegeben: "Es sollte nur einen Weg geben, um ein Problem zu lösen." Mehrfachauswahl ist in der Kunst (Meinungsfreiheit) groß, in der Technik jedoch mies.

3
Nihal Sahu

Die ++-Klasse von Operatoren sind Ausdrücke mit Nebenwirkungen. Dies ist in der Regel in Python nicht zu finden.

Aus demselben Grund ist eine Zuweisung kein Ausdruck in Python und verhindert somit das übliche if (a = f(...)) { /* using a here */ }-Idiom.

Schließlich vermute ich, dass der Operator mit der Pythons-Referenzsemantik nicht sehr konsistent ist. Denken Sie daran, dass Python keine Variablen (oder Zeiger) mit der aus C/C++ bekannten Semantik hat.

2
Ber

so wie ich es verstanden habe, werden Sie nicht glauben, dass der Wert im Speicher geändert wird . in c wenn Sie x ++ ausführen, ändert sich der Wert von x im Speicher da hat noch x nicht x + 1. Wenn Sie x ++ schreiben, denken Sie, dass x change tatsächlich passiert, dass x refrence an einen Ort im Speicher geändert wird, an dem x + 1 gespeichert ist. Oder erstellen Sie diesen Ort neu, falls keine vorhanden ist. 

2
rafi wiener

Eine bessere Frage wäre vielleicht die Frage, warum es diese Operatoren in C gibt. K & R bezeichnet Operatoren als "ungewöhnlich" (Abschnitt 2.8, Seite 46). In der Einleitung werden sie als "prägnanter und oft effizienter" bezeichnet. Ich vermute, dass die Tatsache, dass diese Operationen immer in der Zeigermanipulation auftauchen, auch eine Rolle in ihrer Einführung gespielt hat .. In Python wurde wahrscheinlich entschieden, dass es keinen Sinn machte, die Inkremente zu optimieren (tatsächlich habe ich nur eine test in C, und es scheint, dass die von gcc generierte Assembly in beiden Fällen addl anstelle von incl verwendet.) Und es gibt keine Zeigerarithmetik. Es wäre also nur eine weitere Möglichkeit gewesen, und wir wissen, dass Python das verabscheut.

1

Ich weiß, dass dies ein alter Thread ist, aber der häufigste Anwendungsfall für ++ i wird nicht behandelt, nämlich das manuelle Indizieren von Sätzen, wenn keine Indizes bereitgestellt werden. In dieser Situation liefert python enumerate ()

Beispiel: Wenn Sie in einer beliebigen Sprache ein Konstrukt wie foreach verwenden, um eine Menge zu durchlaufen, sagen wir im Beispiel sogar, dass es sich um eine ungeordnete Menge handelt und dass Sie einen eindeutigen Index benötigen, um sie voneinander zu unterscheiden

i = 0
stuff = {'a': 'b', 'c': 'd', 'e': 'f'}
uniquestuff = {}
for key, val in stuff.items() :
  uniquestuff[key] = '{0}{1}'.format(val, i)
  i += 1

In solchen Fällen bietet python eine Aufzählungsmethode, z.

for i, (key, val) in enumerate(stuff.items()) :
0
Jessica Pennell

Um bereits gute Antworten auf dieser Seite zu vervollständigen:

Nehmen wir an, wir entscheiden uns dazu, das Präfix (++i), das die unären + und - Operatoren bricht.

Heutzutage macht das Präfix mit ++ oder -- nichts, da es den unären Plus-Operator zweimal (nichts) oder zweimal zweimal (zweimal: sich selbst abbricht) ermöglicht.

>>> i=12
>>> ++i
12
>>> --i
12

Das würde also diese Logik möglicherweise brechen.

Ich denke, das bezieht sich auf die Begriffe der Veränderlichkeit und Unveränderlichkeit von Objekten. 2,3,4,5 sind in Python unveränderlich. Siehe das Bild unten. 2 hat bis zu diesem Python-Prozess eine feste ID. 

 ID of constants and variables

x ++ würde im Wesentlichen ein In-Place-Inkrement wie C bedeuten. In C führt X ++ In-Place-Inkremente aus. Also ist x = 3 und x ++ würde 3 im Speicher auf 4 erhöhen, im Gegensatz zu Python, wo 3 noch im Speicher vorhanden wäre. 

In Python müssen Sie also keinen Wert im Speicher neu erstellen. Dies kann zu Leistungsoptimierungen führen. 

Dies ist eine ahnungslose Antwort.

0
Pikesh Prasoon