Czy można zastąpić + = w Pythonie?Przesłanianie "+ =" w Pythonie? (__iadd __() metoda)
Odpowiedz
Tak, należy zastąpić metodę __iadd__
. Przykład:
def __iadd__(self, other):
self.number += other.number
return self
Nie powinieneś zaimplementować '__iadd__', jeśli twoja klasa reprezentuje niezmienne obiekty. W takim przypadku wystarczy zaimplementować '__add__', który będzie zastępował' + = '. Na przykład możesz użyć '+ =' na niezmiennych typach, takich jak łańcuchy i liczby całkowite, których nie można wykonać za pomocą '__iadd__'. –
@ScottGriffiths, więc czy mówisz, że jeśli zaimplementowałeś '__add__', to niekoniecznie musisz implementować' __iadd__'? Przeczytałem zduplikowane pytanie, które podłączyłeś, ale właśnie się pogubiłem, ponieważ nie rozumiem, dlaczego chcesz zaimplementować '__add__', aby zmutował obiekt –
@ScottGriffiths oznaczało pytanie" nie musisz koniecznie implementować '__iadd__' __do użycia + = __? " –
http://docs.python.org/reference/datamodel.html#emulating-numeric-types
Na przykład, w celu wykonania instrukcji x + = y, gdzie x jest wystąpienie klasy, posiada metody __iadd __(), x .__ iadd__ (y) jest wywoływane.
Poza przeciążeniem __iadd__
(pamiętaj, aby wrócić siebie!), Można również awaryjne na __add__
, a x + y = zadziała jak x = x + y. (Jest to jedna z pułapek operatora + =.)
>>> class A(object):
... def __init__(self, x):
... self.x = x
... def __add__(self, other):
... return A(self.x + other.x)
>>> a = A(42)
>>> b = A(3)
>>> print a.x, b.x
42 3
>>> old_id = id(a)
>>> a += b
>>> print a.x
45
>>> print old_id == id(a)
False
nawet trips up experts:
class Resource(object):
class_counter = 0
def __init__(self):
self.id = self.class_counter
self.class_counter += 1
x = Resource()
y = Resource()
Jakie wartości można się spodziewać x.id
, y.id
i Resource.class_counter
mieć?
Twój drugi przykład nie ma nic wspólnego z iadd ani + =. Ten sam wynik występuje, jeśli użyjesz self.class_counter = self.class_counter + 1 To tylko problem z określeniem zakresu, używając self, kiedy należy użyć Resource. – FogleBird
Jest to przykład użycia + = może prowadzić do problemów. Jeśli przeładowujesz __iadd__, to otwierasz użytkowników swojej klasy (włączając w to siebie) do tego i, przynajmniej, powinieneś wiedzieć, że problem istnieje wcześniej. –
@FogleBird: To jest błąd, ponieważ 'foo + = bar' może oznaczać" zmutować istniejący obiekt, który 'foo' oznacza" lub "przypisać' foo' do obiektu wynikającego z wyrażenia 'foo + bar'". A to, co się dzieje, zależy od tego, czy 'foo' ma metodę' __iadd__'. – Claudiu
Oprócz co prawidłowo podano w odpowiedzi powyżej, warto wyraźnie wyjaśnić, że kiedy __iadd__
jest nadpisane, operacja x += y
nie kończy się wraz z końcem __iadd__
metody.
Zamiast tego kończy się x = x.__iadd__(y)
. Innymi słowy, Python przypisuje wartość zwracaną przez implementację do obiektu, do którego "dodajesz", PO zakończeniu implementacji.
Oznacza to, że możliwe jest zmutowanie lewej strony operacji x += y
, aby nie zakończył się ostatni niejawny krok. Zastanów się, co może się zdarzyć podczas dodawania do czegoś, co jest w liście:
>>> x[1] += y # x has two items
Teraz, jeśli realizacja __iadd__
(metoda obiektu w x[1]
) omyłkowo lub celowo usuwa pierwszy element (x[0]
) od początku listy, Python uruchomi następnie twoją metodę __iadd__
) spróbuj przypisać jej wartość zwracaną do x[1]
. Który już nie będzie istnieć (będzie to x[0]
), w wyniku czego powstanie ÌndexError
.
Lub, jeśli __iadd__
wkładki coś do początku x
powyższego przykładu, Twój obiekt będzie na x[2]
, nie x[1]
, a co było wcześniej w x[0]
będzie teraz w x[1]
i przypisać wartość zwracaną przez __iadd__
wezwanie.
O ile nie wiadomo, co się dzieje, powstałe błędy mogą być koszmarem do naprawienia.
- 1. Przesłanianie metody statyczne w Pythonie
- 2. Enum metoda przesłanianie
- 3. C++ wirtualna metoda przesłanianie
- 4. Dziedziczenie i przesłanianie __init__ w Pythonie
- 5. Metoda wielokrotnego przypisywania w Pythonie
- 6. scala przesłanianie java metoda klasy, która odwołuje klasa wewnętrzna
- 7. Przesłanianie "wymagać" w Clojure?
- 8. Przesłanianie motywów w WPF
- 9. Metoda wywołania w Pythonie bez 'self'
- 10. Klasa list w Pythonie __contains__ Metoda funkcjonalności
- 11. Metoda Otsu i filtr Median w Pythonie
- 12. Jaka jest najlepsza metoda w Pythonie?
- 13. Przesłanianie hasłem
- 14. Przesłanianie fasoli w testach integracji
- 15. Przesłanianie grafiki emoji
- 16. C++ Problem przesłanianie/przeciążenie
- 17. Przesłanianie stylu CSS
- 18. Ocena wyrażeń boolowskich w Pythonie
- 19. C# Przesłanianie metody GetHashCode
- 20. Bower zależność przesłanianie
- 21. Playframework 2.3.9 Zależność przesłanianie
- 22. maszynopis przesłanianie toString()
- 23. Przesłanianie php.ini na serwerze
- 24. Przesłanianie funkcji analizy szkieletu
- 25. Przesłanianie strony trzeciej JS
- 26. Dockerfile Przesłanianie zmiennej ENV
- 27. warunkowy (SFINAE) przesłanianie
- 28. Django: przesłanianie Model.validate_unique
- 29. Selen: Dlaczego moja metoda get_cookies() zwróciła listę w Pythonie?
- 30. Czy metoda readline w Pythonie rozpoznaje obie odmiany linii?
Dokładny duplikat http://stackoverflow.com/questions/728361/is-there-a-way-to-overload-in-python –
Tak, ale za pomocą wyszukiwania w witrynie: + = python nie daje wyników. umieszczanie cudzysłowów wokół "+ =" daje wyniki, ale w większości nieistotne sędziowanie przez nagłówki. znaleźć to za pomocą wyszukiwarki Google. –