Czy dziedziczenie z obiektu Pythona w Pythonie 3.x jest konieczne lub przydatne?

94

W starszej wersji Pythona, kiedy tworzysz klasę w Pythonie, może ona dziedziczyć z obiektu, który jest, o ile rozumiem, specjalny wbudowany element Pythona, który pozwala twojemu obiektowi być obiektem w nowym stylu.

A co z nowszą wersją (> 3.0 i 2.6)? Przeszukałem obiekt klasy, ale otrzymałem tak dużo wyników (z oczywistych powodów). Jakaś wskazówka?

Podziękować!

Tomasz
źródło
2
Jeśli twój kod będzie również używany w wersji 2.x, dobrze jest być wyraźny.
smci
1
Odpowiedź jest dobra w tym pytaniu: stackoverflow.com/questions/4015417/ ...
nngeek

Odpowiedzi:

94

Nie musisz dziedziczyć z, objectaby mieć nowy styl w Pythonie 3. Wszystkie klasy są w nowym stylu.

SilentGhost
źródło
5
Zauważ, że oznacza to, że wszystkie klasy dziedziczą objectniezależnie od tego, czy (object)
wpisują
8
Nie musisz, ale „Porting Python code to Python 3” mówi, że jest nadal ważny: docs.python.org/py3k/howto/pyporting.html#subclass-object Również: docs.python.org/reference/ …
hyperboreean
Z tego posta wspomnianego w komentarzu nngeek, wydaje się, że dobrym, stabilnym odniesieniem dla starego i nowego stylu (naprawdę dotyczy tylko Py2) jest: docs.python.org/2/reference/ ... - powyższe linki wydawały się mieć od czasu zmiany.
Eric Cousineau
80

Zdaję sobie sprawę, że to stare pytanie, ale warto zauważyć, że nawet w Pythonie 3 te dwie rzeczy nie są tym samym.

Jeśli wyraźnie dziedziczysz po object, to, co faktycznie robisz, jest dziedziczeniem builtins.object niezależnie od tego, na co to wskazuje w danym momencie.

Dlatego mógłbym mieć jakiś (bardzo zwariowany) moduł, który z jakiegoś powodu nadpisuje obiekt. Nazwijmy ten pierwszy moduł „newobj.py”:

import builtins

old_object = builtins.object  # otherwise cyclic dependencies

class new_object(old_object):

    def __init__(self, *args, **kwargs):
        super(new_object, self).__init__(*args, **kwargs)
        self.greeting = "Hello World!" 

builtins.object = new_object  #overrides the default object

Następnie w innym pliku („klasses.py”):

class Greeter(object):
    pass

class NonGreeter:
    pass

Następnie w trzecim pliku (który faktycznie możemy uruchomić):

import newobj, klasses  # This order matters!

greeter = klasses.Greeter()
print(greeter.greeting)  # prints the greeting in the new __init__

non_greeter = klasses.NonGreeter()
print(non_greeter.greeting) # throws an attribute error

Możesz więc zobaczyć, że w przypadku, gdy dziedziczenie jest jawne po obiekcie, uzyskujemy inne zachowanie niż wtedy, gdy zezwalasz na niejawne dziedziczenie.

Philip Adler
źródło
14
Jest to istotne, ponieważ generalnie oczekuje się, że zachowanie jest równoważne. To nie jest równoważne, stąd moje spostrzeżenia.
Philip Adler