2012-04-08 23 views
70

Czy istnieje jakakolwiek reguła dotycząca tego, które wbudowane i standardowe klasy bibliotek nie są podklasowalne ("końcowe")?Które klasy nie mogą być poddane podklasie?

Jak Pythona 3.3, oto kilka przykładów:

  • bool
  • function
  • operator.itemgetter
  • slice

znalazłem question która zajmuje się realizacji "końcowe" klasy, oba w C i czysty Python.

Chciałbym zrozumieć, jakie powody mogą wyjaśniać, dlaczego dana klasa została wybrana jako "ostateczna".

+4

'NoneType' jest kolejnym przykładem. – Duncan

+4

Czy klasa końcowa w jednej implementacji Pythona może być podklasowalna w innej implementacji? Mam nadzieję, że ktoś może potwierdzić, że to się nigdy nie zdarza. W przeciwnym razie, kod napisany dla jednej implementacji może się zepsuć po przeniesieniu na inny (bardzo boleśnie też: wyobrazić sobie, że ktoś podklasł się 'funkcją', a teraz musi refodować kod, aby uniknąć tego dziedziczenia). – max

+3

Należy zauważyć, że PyPy odmawia również podklasowania czterech przykładów ... nawet jeśli nie ma ograniczenia CPython. Mogą mieć powód udokumentowany w ich bazie kodów. –

Odpowiedz

23

Wydaje się, że dwa powody, dla których klasa jest "ostateczna" w Pythonie.

1. naruszenie klasy niezmienną

klas, które następują Singleton mieć niezmienne, że istnieje ograniczona (wstępnie określony) Liczba przypadków. Każde naruszenie tego niezmiennika w podklasie będzie niezgodne z intencją klasy i nie będzie działało poprawnie. Przykłady:

  • bool: True, False; zobacz Guido's comments
  • NoneType: None
  • NotImplementedType: NotImplemented
  • ellipsis: Ellipsis

Mogą wystąpić przypadki, inne niż wzorzec Singleton w tej kategorii, ale nie jestem świadomy żadnych.

2. Nie Persuasive Use Case

klasy A realizowany w C wymaga dodatkowej pracy, aby umożliwić podklasy (przynajmniej w CPython). Wykonanie takiej pracy bez przekonującego zastosowania nie jest zbyt atrakcyjne, więc wolontariusze są mniej skłonni wystąpić. Przykłady:

Uwaga 1:

I początkowo myślałem było ważne przypadki użycia, ale po prostu niewystarczające zainteresowanie, w podklasy z function i operator.itemgetter. Dzięki @agf za wskazanie, że przypadki użycia oferowane here i here nie są przekonujące (zobacz @agf komentarze do pytania).

Uwaga 2:

Obawiam się, że kolejna implementacja Pythona może przypadkowo pozwalają instacji klasy, która jest ostateczna w CPython. Może to spowodować powstanie nieprzenośnego kodu (przypadek użycia może być słaby, ale ktoś może nadal pisać kod podklasowy function, jeśli obsługuje go Python). Można to rozwiązać, zaznaczając w dokumentacji Pythona wszystkie wbudowane i standardowe klasy bibliotek, których nie można poddać podklasie, i wymagając, aby wszystkie implementacje podążały za zachowaniem CPython w tym zakresie.

Uwaga 3:

Komunikat produkowane przez CPython we wszystkich powyższych przypadkach:

TypeError: type 'bool' is not an acceptable base type 

Jest to dość tajemnicze, jak wiele pytań na ten temat show. Prześlę sugestię, aby dodać akapit do dokumentacji wyjaśniającej klasy końcowe, a może nawet zmienić komunikat o błędzie na:

TypeError: type 'bool' is final (non-extensible) 
+3

Oczywiście, jeśli pisałeś symulację kota Schrodingera, możesz chcieć podklasy 'bool' włączyć' nieznane' :-P tylko żartuję – Endophage

+8

@Endophage: Qbit z pewnością byłby przydatny, ale nie jest podlaską 'bool', wręcz przeciwnie, każda wartość boolowska jest rodzajem qbit! jedno, które się zaobserwuje. Prawdopodobnie poradziłbym sobie z tą sprawą z '__subclasscheck__' i przyjaciółmi. – SingleNegationElimination

+4

@TokenMacGuy doskonała obserwacja! Dlaczego więc nie mamy klasy Qbit w Pythonie, której bool jest podklasą! Żądam, żeby tak było! :-P – Endophage

Powiązane problemy