Dlaczego w Pythonie nie ma operatorów ++ i--?

Dlaczego w Pythonie nie ma operatorów ++ i --?

Author: animuson, 2010-09-07

17 answers

To nie dlatego, że to nie ma sensu; ma sens definiowanie "x++" jako "x + = 1, oceniając do poprzedniego powiązania x".

Jeśli chcesz poznać oryginalny powód, musisz albo przebrnąć przez stare listy dyskusyjne Pythona lub zapytać kogoś, kto tam był (np. Guido), ale łatwo jest uzasadnić po fakcie:

Proste zwiększanie i zmniejszanie nie są potrzebne tak bardzo, jak w innych językach. Nie piszesz często takich rzeczy jak for(int i = 0; i < 10; ++i) w Pythonie, zamiast tego robić rzeczy takie jak for i in range(0, 10).

Ponieważ nie jest tak często potrzebna, jest znacznie mniej powodów, aby nadać jej własną specjalną składnię; kiedy trzeba ją zwiększyć, += jest zwykle w porządku.

To nie jest decyzja, czy to ma sens,czy można to zrobić-robi, i może. Pytanie, czy warto dodać tę korzyść do podstawowej składni języka. Pamiętaj, że są to cztery operatory-postinc, postdec, preinc, predec, a każdy z nich będzie potrzebował aby mieć własne przeciążenia klas; wszystkie muszą być określone i przetestowane; dodałoby to kody opcodes do języka (sugerując większy, a zatem wolniejszy, silnik VM); każda klasa, która obsługuje logiczny przyrost, musiałaby je zaimplementować (na górze += i -=).

To wszystko jest zbędne z += i -=, więc stałoby się stratą netto.

 380
Author: Glenn Maynard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-06 23:57:42

Ta oryginalna odpowiedź, którą napisałem, jest mitem z folkloru informatyki : obalona przez Dennisa Ritchie jako "historycznie niemożliwa", jak zauważono w listach do redaktorów Communications of the ACM July 2012 Doi:10.1145/2209249.2209251


Operatory increment/decrement C zostały wymyślone w czasie, gdy kompilator C nie był zbyt inteligentny i autorzy chcieli być w stanie określić bezpośrednią intencję, że operator języka maszynowego powinien być używany co zapisało kilka cykli dla kompilatora, który może wykonać

load memory
load 1
add
store memory

Zamiast

inc memory 

I PDP-11 obsługiwały nawet instrukcje" autoincrement "i" autoincrement deferred " odpowiadające odpowiednio *++p i *p++. Patrz punkt 5.3 instrukcji jeśli jesteś strasznie ciekawy.

Ponieważ Kompilatory są wystarczająco inteligentne, aby obsługiwać sztuczki optymalizacji wysokiego poziomu wbudowane w składnię C, są teraz tylko wygodą składniową.

Python nie ma sztuczek, aby przekazać intencje asemblerowi, ponieważ nie używa takiego.

 78
Author: msw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-07 16:48:33

Zawsze zakładałem, że ma to związek z tą linią Zen Pythona:

Powinien być jeden - a najlepiej tylko jeden-oczywisty sposób, aby to zrobić.

X++ i x+=1 robią dokładnie to samo, więc nie ma powodu, aby mieć oba.

 52
Author: GSto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-03 00:22:39

Oczywiście moglibyśmy powiedzieć "Guido właśnie zdecydował się w ten sposób" , ale myślę, że pytanie dotyczy naprawdę powodów tej decyzji. Myślę, że jest kilka powodów:

  • miesza ze sobą wypowiedzi i wyrażenia, co nie jest dobrą praktyką. Zobacz http://norvig.com/python-iaq.html
  • ogólnie zachęca ludzi do pisania mniej czytelnego kodu
  • dodatkowa złożoność implementacji języka, która jest niepotrzebna w Pythonie, jak już wspomniane
 36
Author: EMP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-07 00:28:13

Ponieważ w Pythonie liczby całkowite są niezmienne (int += faktycznie zwraca inny obiekt).

Ponadto, z ++/-- musisz się martwić o pre-versus post-increment/decrement, i potrzeba tylko jednego naciśnięcia klawisza, aby napisać x+=1. Innymi słowy, pozwala uniknąć potencjalnego zamieszania kosztem bardzo małego zysku.

 13
Author: Nathan Davis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-07 00:25:03

Jasność!

Python jest dużo oklarowności i żaden programista nie jest w stanie poprawnie odgadnąć znaczenia --a, chyba że nauczy się języka o takiej konstrukcji.

Python jest również dużo ounikanie konstruktów, które zapraszają błędy i operatory ++ są znane jako bogate źródła wad. Te dwa powody są wystarczające, aby nie mieć tych operatorów w Pythonie.

Decyzja, że Python używa wcięć do oznaczania bloków raczej niż środki składniowe, takie jak jakaś forma begin/end bracketing lub obowiązkowe oznakowanie końcowe opiera się w dużej mierze na tych samych względach.

Dla ilustracji, spójrz na dyskusję wokół wprowadzenia operatora warunkowego (W C: cond ? resultif : resultelse) do Pythona w 2005 roku. Przeczytaj przynajmniej pierwszą wiadomość i wiadomość decyzyjną z tej dyskusji (która miała kilka prekursorów na ten sam temat wcześniej).

Ciekawostki: PEP często wspomniane w nim jest " Python extension Proposal "PEP 308. LC oznacza rozumienie listy , GE oznacza wyrażenie generatora (i nie martw się, jeśli ci się mylą, nie są to żadne z niewielu skomplikowanych miejsc Pythona).

 12
Author: Lutz Prechelt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-16 17:27:54

Po prostu tak to zaprojektowano. Operatory Increment i decrement są tylko skrótami dla x = x + 1. Python zazwyczaj przyjął strategię projektowania, która zmniejsza liczbę alternatywnych sposobów wykonywania operacji. Augmented assignment jest najbliższą rzeczą do operatorów inkrementacji/dekrementacji w Pythonie, a zostały one dodane dopiero w Pythonie 2.0.

 9
Author: Reed Copsey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-06 23:37:27

Jestem bardzo nowy w Pythonie, ale podejrzewam, że powodem jest nacisk między zmiennymi i niezmiennymi obiektami w języku. Wiem, że x++ można łatwo zinterpretować jako x = x + 1, ale wygląda na to, że inkrementujesz in-place obiekt, który może być niezmienny.

Tylko moje przypuszczenie / przeczucie / przeczucie.

 8
Author: mkoistinen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-07 00:11:00

Moje zrozumienie, dlaczego python nie ma operatora ++ jest następujące: kiedy piszesz to w Pythonie a=b=c=1 otrzymasz trzy zmienne (etykiety) wskazujące na ten sam obiekt (którego wartość to 1). Można to sprawdzić za pomocą funkcji id, która zwróci adres pamięci obiektu:

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

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

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

Wszystkie trzy zmienne (etykiety) wskazują na ten sam obiekt. Teraz zwiększ zmienną i zobacz, jak wpływa ona na adresy pamięci:

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

Widać, że zmienna a wskazuje teraz na inny obiekt jako zmienne b i c. Ponieważ użyłeś a = a + 1 jest to wyraźnie jasne. Innymi słowy przypisujesz zupełnie inny obiekt do label a. Wyobraź sobie, że możesz napisać a++ sugerowałoby to, że nie przypisałeś do zmiennej a nowego obiektu, ale ratter inkrementował Stary. Wszystko to jest IMHO dla minimalizacji zamieszania. Aby lepiej zrozumieć, zobacz jak działają zmienne Pythona:

W Pythonie, dlaczego funkcja może modyfikować niektóre argumenty postrzegane przez rozmówca, ale nie inni?

Czy Python call-by-value czy call-by-reference? Ani jedno, ani drugie.

Czy Python przekazuje wartość, czy referencję?

Czy Python pass-by-reference czy pass-by-value?

Python: jak przekazać zmienną przez odniesienie?

Zrozumienie zmiennych Pythona i zarządzanie pamięcią

Emulacja zachowania pass-by-value w Pythonie

Python funkcje wywołane przez referencję

Code Like A Pythonist: Idiomatic Python

 7
Author: Wakan Tanka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:25:55

Wierzę, że z Credo Pythona wynika, że "explicit jest lepszy niż implicit".

 4
Author: Sepheus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-07 10:15:14

Po pierwsze, Python ma tylko pośredni wpływ na C; jest pod silnym wpływem ABC , które najwyraźniej nie ma tych operatorów , więc nie powinno być niespodzianką, aby nie znaleźć ich również w Pythonie.

Po drugie, jak mówili inni, przyrost i przyrost są już wspierane przez += i -=.

Po trzecie, pełne wsparcie dla zbioru operatorów ++ i -- zazwyczaj obejmuje obsługę zarówno ich wersji prefiksowych, jak i postfixowych. W C i C++, może to prowadzić do wszelkiego rodzaju" uroczych " konstrukcji, które wydają się (dla mnie) być sprzeczne z duchem prostoty i prostoty, którą obejmuje Python.

Na przykład, podczas gdy twierdzenie C while(*t++ = *s++); może wydawać się proste i eleganckie dla doświadczonego programisty, dla kogoś uczącego się, nie jest proste. Dorzuć mieszankę przedrostków i postfixów przyrostów i przyrostów, a nawet wielu profesjonalistów będzie musiało się zatrzymać i pomyśleć trochę.

 4
Author: wberry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-12 18:04:48

Być może dlatego, że @ GlennMaynard patrzy na sprawę tak, jak w porównaniu z innymi językami, ale w Pythonie robi się rzeczy po Pythonie. To nie pytanie "dlaczego". Jest tam i możesz robić rzeczy z takim samym skutkiem za pomocą x+=. W Zen Pythona podano: "powinien być tylko jeden sposób rozwiązania problemu."Wielokrotne wybory są świetne w sztuce (wolność wypowiedzi), ale kiepskie w inżynierii.

 3
Author: Nihal Sahu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:28

Jak to zrozumiałem, więc nie pomyślisz, że wartość w pamięci została zmieniona. w c gdy robisz x++ zmienia się wartość x w pamięci. ale w Pythonie wszystkie liczby są niezmienne, stąd adres, na który wskazuje x, nadal ma x, a nie x+1. pisząc X++ można by pomyśleć, że X zmienia to, co naprawdę się dzieje, to to, że X refrence jest zmieniany na miejsce w pamięci, gdzie x+1 jest przechowywany lub odtworzyć tę lokalizację, jeśli Doe ' s nie istnieje.

 2
Author: rafi wiener,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-17 14:41:19

Klasa ++ operatorów to wyrażenia z efektami ubocznymi. Jest to coś, czego generalnie nie można znaleźć w Pythonie.

Z tego samego powodu przypisanie nie jest wyrażeniem w Pythonie, co uniemożliwia wspólny idiom if (a = f(...)) { /* using a here */ }.

Na koniec podejrzewam, że nie są zbyt zgodne z semantyką odniesienia Pythona. Pamiętaj, że Python nie posiada zmiennych (lub wskaźników) o semantyce znanej z C/C++.

 2
Author: Ber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-12 09:51:04

Może lepszym pytaniem byłoby zapytać, dlaczego te operatory istnieją w C. K&R nazywa operatory increment i decrement "nietypowe" (sekcja 2.8 strona 46). We wstępie określa się je jako "bardziej zwięzłe i często skuteczniejsze". Podejrzewam, że fakt, że operacje te zawsze pojawiają się w manipulacji wskaźnikiem również odegrał rolę w ich wprowadzeniu. W Pythonie prawdopodobnie zdecydowano, że nie ma sensu próbować optymalizować przyrosty (w rzeczywistości właśnie zrobiłem test w C i wydaje się, że że generowany przez gcc assembly używa addl zamiast incl w obu przypadkach) i nie ma arytmetyki wskaźników; więc byłoby to tylko jeszcze jeden sposób, aby to zrobić i wiemy, że Python nienawidzi tego.

 1
Author: Ludovico Fischer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-07 00:11:43

Aby uzupełnić już dobre odpowiedzi na tej stronie:

Załóżmy, że zdecydujemy się to zrobić, prefiks (++i), który złamałby jednoargumentowe operatory + i -.

Dzisiaj prefiks przez ++ lub -- nie robi nic, ponieważ umożliwia operator unary plus dwa razy (nie robi nic) lub unary minus dwa razy (anuluje się sam)

>>> i=12
>>> ++i
12
>>> --i
12
Więc to może złamać tę logikę.
 0
Author: Jean-François Fabre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-26 09:00:38

Operator++ nie jest dokładnie taki sam jak operator+=. W rzeczywistości wynik obu jest taki sam, ale zastosowania mają pewną różnicę. Na przykład, możesz użyć operatora ++ w ternary conditional, for loop, etc, ale nie możesz użyć +=. Na dole czujemy potrzebę i..., z tego powodu.

 -3
Author: Coker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-12 09:34:43