meaning Perché non ci sono operatori++ e-in Python?




python// division (14)

Ho sempre pensato che avesse a che fare con questa linea dello zen di python:

Ci dovrebbe essere uno - e preferibilmente solo uno - modo ovvio per farlo.

x ++ e x + = 1 fanno esattamente la stessa cosa, quindi non c'è motivo di averli entrambi.

Perché non ci sono operatori ++ e -- in Python?


Credo che derivi dal credo di Python che "esplicito è meglio di implicito".


Perché, in Python, gli interi sono immutabili (int's + = restituisce effettivamente un oggetto diverso).

Inoltre, con ++ / - è necessario preoccuparsi di pre-versus post-incremento / decremento, e ci vuole solo un altro tasto per scrivere x+=1 . In altre parole, evita la potenziale confusione a scapito di guadagni minimi.


Certo, potremmo dire "Guido ha deciso in quel modo", ma penso che la domanda riguardi davvero le ragioni di quella decisione. Penso che ci siano diversi motivi:

  • Mescola insieme dichiarazioni ed espressioni, che non è una buona pratica. Vedi http://norvig.com/python-iaq.html
  • Generalmente incoraggia le persone a scrivere codice meno leggibile
  • Extra complessità nell'implementazione del linguaggio, che non è necessaria in Python, come già menzionato

Sono molto nuovo a Python ma sospetto che la ragione sia dovuta all'enfasi tra oggetti mutevoli e immutabili all'interno del linguaggio. Ora, so che x ++ può essere facilmente interpretato come x = x + 1, ma sembra che tu stia aumentando sul posto un oggetto che potrebbe essere immutabile.

Solo la mia ipotesi / sentimento / intuizione.


L'operatore ++ non è esattamente uguale all'operatore + =. In effetti il ​​risultato di entrambi è lo stesso, ma gli usi hanno qualche differenza. Ad esempio, puoi usare l'operatore ++ in condizionale ternario, per il ciclo, ecc ma non puoi usare + =. In fondo, sentiamo il bisogno ++ e -, per questo motivo.


Primo, Python è influenzato solo indirettamente da C; è fortemente influenzato dalla ABC , che a quanto pare non ha questi operatori , quindi non dovrebbe essere una grande sorpresa non trovarli neanche in Python.

In secondo luogo, come altri hanno già detto, l'incremento e il decremento sono supportati da += e -= già.

In terzo luogo, il supporto completo per un insieme di operatori ++ e -- include in genere il supporto di entrambe le versioni di prefisso e suffisso. In C e C ++, questo può portare a tutti i tipi di costrutti "adorabili" che sembrano (per me) essere contrari allo spirito di semplicità e rettitudine che Python abbraccia.

Ad esempio, mentre l'istruzione C while(*t++ = *s++); può sembrare semplice ed elegante per un programmatore esperto, per qualcuno che lo apprende, è tutt'altro che semplice. Getta una combinazione di incrementi e decrementi di prefisso e postfix, e anche molti professionisti dovranno fermarsi e pensare un po '.


Questa originale risposta che ho scritto è un mito del folklore dell'informatica : smentito da Dennis Ritchie come "storicamente impossibile" come indicato nelle lettere agli editori di Communications of the ACM luglio 2012 doi:10.1145/2209249.2209251

Gli operatori di incremento / decremento C sono stati inventati in un momento in cui il compilatore C non era molto intelligente e gli autori volevano essere in grado di specificare l'intento diretto di utilizzare un operatore di linguaggio macchina che salvasse una manciata di cicli per un compilatore che potrebbe fare a

load memory
load 1
add
store memory

invece di

inc memory 

e il PDP-11 supportava anche le istruzioni "autoincrement" e "autoincrement deferred" corrispondenti rispettivamente a *++p e *p++ . Vedere la sezione 5.3 del manuale se è orribilmente curioso.

Poiché i compilatori sono abbastanza intelligenti da gestire i trucchi di ottimizzazione di alto livello incorporati nella sintassi di C, ora sono solo una comodità sintattica.

Python non ha trucchi per comunicare le intenzioni all'assemblatore perché non ne usa uno.


La classe ++ degli operatori sono espressioni con effetti collaterali. Questo è qualcosa che generalmente non si trova in Python.

Per lo stesso motivo, un assegnamento non è un'espressione in Python, impedendo così il comune if (a = f(...)) { /* using a here */ } idioma if (a = f(...)) { /* using a here */ } .

Infine sospetto che l'operatore non sia molto coerente con la semantica di riferimento di Python. Ricorda, Python non ha variabili (o puntatori) con la semantica nota da C / C ++.


Chiarezza!

Python ha molto a che fare con la chiarezza e nessun programmatore è in grado di indovinare correttamente il significato di --a meno che non abbia imparato una lingua con quel costrutto.

Python si occupa anche di evitare costrutti che invitano errori e gli operatori ++ sono noti per essere ricche fonti di difetti. Queste due ragioni sono sufficienti per non avere quegli operatori in Python.

La decisione secondo cui Python utilizza il rientro per contrassegnare i blocchi piuttosto che i mezzi sintattici come una forma di parentesi iniziale / finale o marcatura di fine obbligatoria si basa in gran parte sulle stesse considerazioni.

Per esempio, cond ? resultif : resultelse un'occhiata alla discussione sull'introduzione di un operatore condizionale (in C: cond ? resultif : resultelse ) in Python nel 2005. Leggete almeno il primo messaggio e il messaggio decisionale di quella discussion (che aveva diversi precursori sullo stesso argomento precedente).

Curiosità: il PEP frequentemente menzionato in esso è la "Proposta di estensione Python" PEP 308 . LC significa comprensione delle liste , GE significa espressione del generatore (e non preoccuparti se ti confondono, non sono nessuno dei pochi punti complicati di Python).


Non è perché non ha senso; ha perfettamente senso definire "x ++" come "x + = 1, valutando il legame precedente di x".

Se vuoi conoscere il motivo originale, dovrai seguire le vecchie mailing list di Python o chiedere a qualcuno che era lì (ad esempio Guido), ma è abbastanza facile giustificare dopo il fatto:

Semplice incremento e decremento non sono necessari tanto quanto in altre lingue. Non scrivi cose come for(int i = 0; i < 10; ++i) in Python molto spesso; invece fai cose come for i in range(0, 10) .

Dato che non è necessario quasi altrettanto spesso, ci sono molte meno ragioni per dargli una propria sintassi speciale; quando hai bisogno di incrementare, += solito va bene.

Non è una decisione se ha senso, o se può essere fatto - lo fa, e può farlo. Si tratta di valutare se il beneficio merita di essere aggiunto alla sintassi principale della lingua. Ricordate, si tratta di quattro operatori: postinc, postdec, preinc, predec e ognuno di questi avrebbe bisogno di avere i propri sovraccarichi di classe; devono tutti essere specificati e testati; aggiungerebbe opcode alla lingua (implicando un motore VM più grande, e quindi più lento); ogni classe che supporta un incremento logico dovrebbe implementarle (sopra += e -= ).

Questo è tutto ridondante con += e -= , quindi diventerebbe una perdita netta.


Forse una domanda migliore sarebbe chiedere perché questi operatori esistono in C. K & R chiama gli operatori di incremento e decremento "insoliti" (Sezione 2.8pagina 46). L'Introduzione li chiama "più concisi e spesso più efficienti". Sospetto che il fatto che queste operazioni si presentino sempre nella manipolazione dei puntatori ha anche avuto un ruolo nella loro introduzione. In Python è stato probabilmente deciso che non aveva senso cercare di ottimizzare gli incrementi (in effetti ho appena fatto un test in C, e sembra che l'assembly generato da gcc usi addl invece di incl in entrambi i casi) e non ci sia aritmetica puntatore; quindi sarebbe stato solo un altro modo per farlo e sappiamo che Python lo detesta.


come ho capito così non penserai che il valore in memoria sia cambiato. in c quando fai x ++ il valore di x nella memoria cambia. ma in python tutti i numeri sono immutabili quindi l'indirizzo che x ha indicato come ancora x non x + 1. quando scrivi x ++ penseresti che x cambi quello che realmente accade è che x refrence è cambiato in una locazione in memoria dove x + 1 è memorizzato o ricrea questa posizione se non esiste.


Per completare già buone risposte su quella pagina:

Supponiamo di decidere di farlo, prefisso ( ++i ) che spezzi gli operatori unari + e -.

Oggi, il prefisso di ++ o -- non fa nulla, perché abilita l'operatore unario più due volte (non fa nulla) o unario meno due volte (due volte: annulla se stesso)

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

In tal modo si romperebbe quella logica.





operators