Właśnie przeprowadził interesujący Test:Dlaczego pyton nie korzysta z __iadd__ dla operatorów sumowanych i przykutych?
~$ python3 # I also conducted this on python 2.7.6, with the same result
Python 3.4.0 (default, Apr 11 2014, 13:05:11)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> class Foo(object):
... def __add__(self, other):
... global add_calls
... add_calls += 1
... return Foo()
... def __iadd__(self, other):
... return self
...
>>> add_calls = 0
>>> a = list(map(lambda x:Foo(), range(6)))
>>> a[0] + a[1] + a[2]
<__main__.Foo object at 0x7fb588e6c400>
>>> add_calls
2
>>> add_calls = 0
>>> sum(a, Foo())
<__main__.Foo object at 0x7fb588e6c4a8>
>>> add_calls
6
Oczywiście metoda __iadd__
jest bardziej skuteczne niż metody __add__
, nie wymagając przydział nowej klasy. Jeśli moje obiekty byłyby wystarczająco skomplikowane, tworzyłoby to niepotrzebne nowe obiekty, potencjalnie tworząc ogromne wąskie gardła w moim kodzie.
Spodziewam się, że w a[0] + a[1] + a[2]
pierwsza operacja będzie wywoływać __add__
, a druga operacja będzie wywoływać __iadd__
na nowo utworzonym obiekcie.
Dlaczego pyton nie optymalizuje tego?
'Suma' jest najczęściej używana dla niezmiennych typów liczbowych, które nie mają metody' __iadd__'. Wydaje mi się, że implementacja specjalnej logiki w celu sprawdzenia metody "__iadd__" spowolniłaby sprawę. –