Po co zwracać NotImplemented zamiast podnoszenia NotImplementedError


281

Python ma singleton o nazwie NotImplemented.

Dlaczego ktoś miałby kiedykolwiek wracać NotImplementedzamiast zgłaszać NotImplementedErrorwyjątek? Czy nie utrudni to tylko znalezienia błędów, takich jak kod, który wykonuje nieprawidłowe metody?

Odpowiedzi:


280

Jest tak, ponieważ __lt__()i powiązane metody porównywania są dość często stosowane pośrednio w sortowaniu list i tym podobne. Czasami algorytm wybiera inną metodę lub wybiera domyślnego zwycięzcę. Zgłoszenie wyjątku wyskoczyłoby z tego rodzaju, chyba że zostanie złapane, podczas NotImplementedgdy nie zostanie podniesione i może zostać użyte w dalszych testach.

http://jcalderone.livejournal.com/32837.html

Podsumowując ten link:

" NotImplementedsygnalizuje środowisku wykonawczemu, że powinien poprosić kogoś innego o wykonanie operacji. W wyrażeniu a == b, jeśli a.__eq__(b)zwraca NotImplemented, to Python próbuje b.__eq__(a). Jeśli bwie wystarczająco dużo, aby powrócić Truelub False, wówczas wyrażenie może się powieść. Jeśli nie, środowisko wykonawcze powróć do wbudowanego zachowania (które opiera się na tożsamości dla ==i !=). ”


5
Byłbym ostrożny z jego użyciem, ponieważ ten link wskazuje na końcu dokumentu.
Jason Coon

16
Kiedy interpreter Pythona sprawdza, czy a.__eq__(b)zwrócił NotImplemented, czy nie może równie łatwo złapać NotImplementedError (i wywołać, b.__eq__(a)czy cokolwiek innego)?
Veky,

24
@Veky. Zgłaszanie wyjątku prawdopodobnie wiąże się z większym nakładem. Wszelkie koszty ogólne w operacji sortowania zostaną powiększone o rozmiar listy, więc nawet jeśli różnica byłaby bardzo mała, nadal byłoby sensowniejsze znalezienie szybszej implementacji. Nie chcesz także wyrwać się z pętli i ponownie je wprowadzić, co wymagałoby implementacji try / catch.
SpliFF,

3
Po pierwsze, jeszcze szybszym rozwiązaniem byłoby automatyczne zsyntetyzowanie lt jako odwróconego gt, zamiast zawsze wywoływania czegoś, co zwróci NotImplemented - a Python tego nie robi. Nie sądzę, że powodem jest tutaj prędkość. Po drugie, nie rozumiem tego, co mówisz: return będzie wymagał tyle samo wyjścia z pętli, co przebicie. W rzeczywistości możesz sobie wyobrazić return jako podniesienie specjalnego wyjątku Return, który zawsze jest zatrzymywany w zakresie wywoływania.
Veky

2
>> „powiększony o rozmiar listy” Przynajmniej, chyba że masz O (n) sort, o którym świat powinien wiedzieć.
Jonathan Hartley

106

Ponieważ mają różne przypadki użycia.

Cytując dokumenty (Python 3.6):

Nie zaimplementowano

powinny być zwracane przez metody specjalnych binarne (np __eq__(), __lt__(),__add__() , __rsub__(), itd.), aby wskazać, że operacja nie jest realizowane w stosunku do innego rodzaju

wyjątek NotImplementedError

[...] W klasach podstawowych zdefiniowanych przez użytkownika metody abstrakcyjne powinny zgłaszać ten wyjątek, gdy wymagają klas pochodnych w celu zastąpienia metody lub podczas opracowywania klasy w celu wskazania, że ​​należy jeszcze dodać rzeczywistą implementację.

Zobacz linki po szczegóły.


13

Jednym z powodów jest wydajność. W sytuacji takiej jak rozbudowane porównania, w których można wykonać wiele operacji w krótkim czasie, konfigurowanie i obsługa wielu wyjątków może zająć dużo więcej czasu niż zwykłe zwrócenie NotImplementedwartości.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.