Zauważam, że operator zmiennej wstępnej / dekrementacji można zastosować do zmiennej (podobnej ++count
). Kompiluje się, ale tak naprawdę nie zmienia wartości zmiennej!
Jakie jest zachowanie operatorów wstępnego zwiększania / zmniejszania (++ / -) w Pythonie?
Dlaczego Python odbiega od zachowania tych operatorów widocznych w C / C ++?
++
i--
operatorów?sta x++
... wynikająca z niej instrukcja atomowa przechowujea
akumulator tam, gdziex
wskazuje, a następnie zwiększax
rozmiar akumulatora. Odbywa się to, ponieważ jest szybsze niż arytmetyka wskaźników, ponieważ jest bardzo powszechna i ponieważ jest łatwa do zrozumienia. Zarówno przed, jak i po.Odpowiedzi:
++
nie jest operatorem. To dwóch+
operatorów.+
Operator jest tożsamość operatora, który nie robi nic. (Wyjaśnienie:+
i-
operatorzy unarne działać tylko na liczbach, ale przypuszczam, że nie można spodziewać się hipotetyczny++
. Operatora do pracy na smyczki)Parses as
Co przekłada się na
Musisz użyć nieco dłuższego
+=
operatora, aby zrobić to, co chcesz:Podejrzewam, że
++
i--
operatorzy zostali pominięci ze względu na spójność i prostotę. Nie znam dokładnego argumentu Guido van Rossuma dotyczącego decyzji, ale mogę sobie wyobrazić kilka argumentów:++count
jest niejednoznaczny, jak mogłaby być+
,+
,count
(dwa unarne+
operatorzy) równie łatwo, jak to może być++
,count
(jeden jednoargumentowy++
operator). Nie jest to znacząca dwuznaczność składniowa, ale istnieje.++
jest niczym więcej niż synonimem+= 1
. To była skróconą wymyślił ponieważ kompilatory C były głupie i nie wiedział, w jaki sposób zoptymalizowaća += 1
doinc
dyspozycji większość komputerów ma. W dzisiejszym dniu optymalizacji kompilatorów i języków interpretowanych za pomocą kodu bajtowego, dodawanie operatorów do języka, aby umożliwić programistom optymalizację kodu, jest zwykle lekceważone, szczególnie w języku takim jak Python, który ma być spójny i czytelny.++
operatorami jest mieszanie różnic (zarówno w wartości pierwszeństwa, jak i wartości zwracanej) między operatorami zwiększania / zmniejszania przed i po zwiększaniu, a Python lubi eliminować język „gotcha” -s. Te kwestie pierwszeństwa z pre- / post-przyrostu C są dość owłosione i niezwykle łatwe do bałagan.źródło
+
operator ma zastosowanie. W przypadku obiektów dziesiętnych. Dziesiętne zaokrągla do bieżącej precyzji.+ +
i++
bez zerwania LL (1).++
to nic innego jak synonim+= 1
. Istnieją warianty ++ przed i po kroku, więc nie jest to oczywiście to samo. Zgadzam się jednak z resztą twoich uwag.Kiedy chcesz zwiększyć lub zmniejszyć, zwykle chcesz to zrobić na liczbach całkowitych. Tak jak:
Ale w Pythonie liczby całkowite są niezmienne . To znaczy, że nie możesz ich zmienić. Wynika to z faktu, że obiektów liczb całkowitych można używać pod kilkoma nazwami. Spróbuj tego:
a i b powyżej są w rzeczywistości tym samym obiektem. Jeśli zwiększysz wartość a, zwiększysz również wartość b. Nie tego chcesz. Więc musisz zmienić przypisanie. Lubię to:
Lub prościej:
Który przeniesie się
b
dob+1
. To nie jest operator inkrementacji, ponieważ nie inkrementujeb
, przypisuje go ponownie.W skrócie: Python zachowuje się tutaj inaczej, ponieważ nie jest to C i nie jest opakowaniem niskiego poziomu wokół kodu maszynowego, ale dynamicznym językiem wysokiego poziomu, w którym przyrosty nie mają sensu, a także nie są tak konieczne, jak w C , gdzie używasz ich na przykład za każdym razem, gdy masz pętlę.
źródło
i++
oznaczałoby przypisaniei + 1
do zmienneji
.i = 5; i++
środki, aby przypisać6
doi
nie modyfikowaćint
obiekt wskazywany przezi
. Oznacza to, że nie oznacza to zwiększenia wartości5
!i++
działa tylko na wartościach lv. Jeślii
miałoby to na celu zwiększenie wskazanego obiektu , to ograniczenie byłoby niepotrzebne.Podczas gdy inne odpowiedzi są poprawne, o ile pokazują, co
+
zwykle robi (a mianowicie pozostaw liczbę taką, jaka jest, jeśli jest jedna), ale są niekompletne, o ile nie wyjaśniają, co się dzieje.Dokładniej,
+x
ocenia dox.__pos__()
i++x
dox.__pos__().__pos__()
.Mogę sobie wyobrazić BARDZO dziwną strukturę klas (dzieci, nie róbcie tego w domu!) W następujący sposób:
źródło
Python nie ma tych operatorów, ale jeśli naprawdę ich potrzebujesz, możesz napisać funkcję o tej samej funkcjonalności.
Stosowanie:
Wewnątrz funkcji musisz dodać locals () jako drugi argument, jeśli chcesz zmienić zmienną lokalną, inaczej spróbuje zmienić globalną.
Również dzięki tym funkcjom możesz:
Ale moim zdaniem następujące podejście jest znacznie jaśniejsze:
Operatory dekrementacji:
Użyłem tych funkcji w moim module tłumaczącym javascript na python.
źródło
Wikipedia
Tak więc, wprowadzając takie operatory, zerwałbyś podział wyrażenia / instrukcji.
Z tego samego powodu nie możesz pisać
jak w niektórych innych językach, w których takie rozróżnienie nie jest zachowane.
źródło
if (n := len(a)) > 10: y = n + 1
na przykład pisać . Zauważ, że rozróżnienie jest wyraźne ze względu na wprowadzenie nowego operatora do tego celu (:=
)TL; DR
Python nie ma jednoargumentowych operatorów inkrementacji / dekrementacji (
--
/++
). Zamiast tego, aby zwiększyć wartość, użyjWięcej szczegółów i gotchas
Ale bądź ostrożny tutaj. Jeśli pochodzisz z C, nawet w Pythonie jest inaczej. Python nie ma „zmiennych” w tym sensie, co C, zamiast tego python używa nazw i obiektów , aw Pythonie
int
są niezmienne.więc powiedzmy, że tak
W pythonie oznacza to: utwórz obiekt typu
int
mający wartość1
i powiąż z nim nazwęa
. Obiekt jest przykłademint
posiadającego wartość1
, a nazwaa
odnosi się do niego. Nazwaa
i obiekt, do którego się odnosi, są różne.Teraz powiedzmy, że tak
Ponieważ
int
s są niezmienne, dzieje się to w następujący sposób:a
do którego się odnosi (jest toint
identyfikator z identyfikatorem0x559239eeb380
)0x559239eeb380
(to jest1
)int
obiekt o wartości2
(ma identyfikator obiektu0x559239eeb3a0
)a
z tym nowym obiektema
odnosi się do obiektu,0x559239eeb3a0
a0x559239eeb380
nazwa obiektu nie odwołuje się już do pierwotnego obiektu ( )a
. Jeśli nie ma żadnych innych nazw odnoszących się do oryginalnego obiektu, zostanie on później wyrzucony.Spróbuj sam:
źródło
Tak, brakowało mi także ++ i - funkcjonalności. Kilka milionów wierszy kodu c zapuściło ten sposób myślenia w mojej starej głowie i zamiast z nim walczyć ... Oto klasa, którą opracowałem:
Oto:
Możesz użyć tego w następujący sposób:
... już mając c, możesz to zrobić ...
....Lub tylko...
... i dla (ponownego) przypisania do liczby całkowitej ...
... podczas gdy to zachowa c jako licznik typów:
EDYTOWAĆ:
A potem jest trochę niespodziewanego (i całkowicie niechcianego) zachowania ,
... ponieważ wewnątrz tej krotki nie jest używane getitem (), zamiast tego do funkcji formatowania przekazywane jest odwołanie do obiektu. Westchnienie. Więc:
... lub, bardziej szczegółowo, i wprost to, co naprawdę chcieliśmy się wydarzyć, chociaż przeciwwskazane w rzeczywistej formie przez gadatliwość (użyj
c.v
zamiast tego) ...źródło
W Pythonie nie ma operatorów post / wstępnej inkrementacji / dekrementacji, jak w językach takich jak C.
Widzimy
++
lub--
mnożymy wiele znaków, tak jak robimy to w matematyce (-1) * (-1) = (+1).Na przykład
Parses as
Co przekłada się na
Ponieważ mnożenie
-
znaku przez-
znak wynosi+
I w końcu,
źródło
-----count
.W Pythonie 3.8+ możesz:
Dzięki temu możesz wiele przemyśleć.
Lub jeśli chcesz napisać coś z bardziej wyrafinowaną składnią (celem nie jest optymalizacja):
Dobrze zwraca 0, jeśli nie istnieje bez błędów, a następnie ustawi ją na 1
źródło