Czy istnieje powód, dla którego deklaracja klasy może dziedziczyć object
?
Właśnie znalazłem kod, który to robi i nie mogę znaleźć dobrego powodu, dla którego to zrobiłbym.
class MyClass(object):
# class code follows...
Czy istnieje powód, dla którego deklaracja klasy może dziedziczyć object
?
Właśnie znalazłem kod, który to robi i nie mogę znaleźć dobrego powodu, dla którego to zrobiłbym.
class MyClass(object):
# class code follows...
Odpowiedzi:
Czy istnieje powód, dla którego deklaracja klasy może dziedziczyć
object
?
W Pythonie 3, oprócz kompatybilności między Pythonem 2 i 3, nie ma powodu . W Python 2 wiele powodów .
W Pythonie 2.x (od wersji 2.2) istnieją dwa style klas w zależności od obecności lub nieobecności object
jako klasy podstawowej:
klasy „klasyczne” : nie mają object
jako klasy podstawowej:
>>> class ClassicSpam: # no base class
... pass
>>> ClassicSpam.__bases__
()
„nowe” klasy stylów : mają, bezpośrednio lub pośrednio (np. dziedziczą po typie wbudowanym ), object
jako klasę podstawową:
>>> class NewSpam(object): # directly inherit from object
... pass
>>> NewSpam.__bases__
(<type 'object'>,)
>>> class IntSpam(int): # indirectly inherit from object...
... pass
>>> IntSpam.__bases__
(<type 'int'>,)
>>> IntSpam.__bases__[0].__bases__ # ... because int inherits from object
(<type 'object'>,)
Bez wątpienia pisząc zajęcia, zawsze będziesz chciał iść na zajęcia w nowym stylu. Korzyści z tego są liczne, aby wymienić niektóre z nich:
Obsługa deskryptorów . W szczególności możliwe są następujące konstrukcje za pomocą deskryptorów:
classmethod
: Metoda, która odbiera klasę jako domyślny argument zamiast instancji.staticmethod
: Metoda, która nie odbiera domyślnego argumentu self
jako pierwszego argumentu.property
: Utwórz funkcje do zarządzania uzyskiwaniem, ustawianiem i usuwaniem atrybutu.__slots__
: Oszczędza zużycie pamięci przez klasę, a także skutkuje szybszym dostępem do atrybutów. Oczywiście nakłada ograniczenia .Metoda __new__
statyczna: pozwala dostosować sposób tworzenia nowych instancji klas.
Kolejność rozstrzygania metod (MRO) : w jakiej kolejności będą wyszukiwane klasy podstawowe klasy podczas próby rozstrzygnięcia, którą metodę wywołać.
Związane z MRO, super
połączenia . Zobacz także, super()
uważane za super.
Jeśli nie dziedziczysz object
, zapomnij o nich. Bardziej wyczerpujący opis poprzednich punktów wypunktowania wraz z innymi dodatkami „nowych” klas stylów można znaleźć tutaj .
Jedną z wad klas nowego stylu jest to, że sama klasa wymaga więcej pamięci. Chyba że tworzysz wiele obiektów klasowych, wątpię, by to był problem, a negatywne zatonięcie w morzu pozytywów.
W Pythonie 3 rzeczy są uproszczone. Istnieją tylko klasy w nowym stylu (zwane po prostu klasami), więc jedyną różnicą w dodawaniu object
jest wymaganie wpisania kolejnych 8 znaków. To:
class ClassicSpam:
pass
jest całkowicie równoważne (oprócz ich nazwy :-) z tym:
class NewSpam(object):
pass
i do tego:
class Spam():
pass
Wszystkie mają object
w sobie __bases__
.
>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]
W Python 2: zawsze dziedzicz po object
jawnie . Zdobądź profity.
W Pythonie 3: dziedzicz, object
jeśli piszesz kod, który próbuje być agnostyczny w Pythonie, to znaczy musi działać zarówno w Pythonie 2, jak i Pythonie 3. W przeciwnym razie nie robi to żadnej różnicy, ponieważ Python wstawia go dla Ciebie za kulisami.
object
. IIRC był moment, w którym nie wszystkie wbudowane typy zostały przeniesione do klas nowego stylu.
object
. Mam już Python 2.2.3 i po szybkim sprawdzeniu nie mogłem znaleźć przestępcy, ale przeredaguję odpowiedź później, aby była bardziej przejrzysta. Byłbym zainteresowany, gdybyś mógł znaleźć przykład, moja ciekawość jest rozbudzona.
object
swoje podstawy.
staticmethod
i classmethod
działa dobrze nawet na lekcjach w starym stylu. property
Sorta działa do odczytu klas starego stylu, po prostu nie przechwytuje zapisów (więc jeśli przypiszesz do nazwy, instancja otrzymuje atrybut o podanej nazwie, który przesłania właściwość). Zauważ też, że __slots__
poprawa szybkości dostępu do atrybutu polega głównie na usunięciu straty, jaką ponosi dostęp do atrybutu klasy w nowym stylu, więc nie jest to tak naprawdę zaletą klas nowego stylu (jednak oszczędność pamięci jest zaletą).
Python 3
class MyClass(object):
= Klasa w nowym styluclass MyClass:
= Klasa w nowym stylu (domyślnie dziedziczy po object
)Python 2
class MyClass(object):
= Klasa w nowym styluclass MyClass:
= KLASA STYLUObjaśnienie :
Podczas definiowania klas podstawowych w Pythonie 3.x możesz usunąć object
definicję. Może to jednak otworzyć drzwi dla poważnie trudnego do wyśledzenia problemu…
Python wprowadził klasy nowego stylu w Pythonie 2.2, a teraz klasy starego stylu są naprawdę dość stare. Dyskusja na temat klas w starym stylu jest zakopana w dokumentach 2.x , a nie istnieje w dokumentach 3.x.
Problemem jest to, składnia klas starym stylu w Pythonie 2.x jest taka sama jak w alternatywnej składni dla klas nowego stylu w Pythonie 3.x . Python 2.x jest nadal bardzo szeroko stosowany (np. GAE, Web2Py), a każdy kod (lub koder) nieświadomie przenoszący definicje klas w stylu 3.x do kodu 2.x skończy się z poważnie nieaktualnymi obiektami podstawowymi. A ponieważ zajęcia w starym stylu nie są niczyje na radarach, prawdopodobnie nie będą wiedzieć, co ich uderzyło.
Po prostu przeliteruj to i ocal łzy jakiegoś programisty w wersji 2.x.
__metaclass__ = type
na górze modułu (po from __future__ import absolute_import, division, print_function
wierszu :-)); jest to hack kompatybilności w Py2, który domyślnie sprawia, że wszystkie później zdefiniowane klasy w module są w nowym stylu, aw Py3 jest całkowicie ignorowany (tylko losowa zmienna globalna siedząca w pobliżu), więc jest nieszkodliwy.
Tak, jest to obiekt „nowego stylu”. To była funkcja wprowadzona w python2.2.
Nowe obiekty mają inny styl obiektowy model do klasycznych obiektów, a niektóre rzeczy nie będzie działać poprawnie ze starymi obiektami typu, na przykład super()
, @property
i deskryptorów. Zobacz ten artykuł, aby uzyskać dobry opis tego, czym jest nowa klasa stylu.
SO link do opisu różnic: Jaka jest różnica między starymi stylami a nowymi klasami stylów w Pythonie?
object
w Pythonie 2.
Historia z Dowiedz się Python na własnej skórze :
Oryginalna interpretacja klasy Pythona została złamana na wiele poważnych sposobów. Gdy ta wada została rozpoznana, było już za późno i musieli ją wesprzeć. Aby rozwiązać problem, potrzebowali stylu „nowej klasy”, aby „stare klasy” nadal działały, ale można użyć nowej, bardziej poprawnej wersji.
Zdecydowali, że użyją słowa „obiekt”, małe litery, aby być „klasą”, po której odziedziczysz klasę. Jest to mylące, ale klasa dziedziczy po klasie o nazwie „obiekt”, aby utworzyć klasę, ale tak naprawdę nie jest to obiekt, to klasa, ale nie zapomnij dziedziczyć po obiekcie.
Również po to, abyś wiedział, jaka jest różnica między klasami w nowym stylu a klasami w starym stylu, jest tak, że klasy w nowym stylu zawsze dziedziczą po object
klasie lub innej klasie, która odziedziczyła po object
:
class NewStyle(object):
pass
Innym przykładem jest:
class AnotherExampleOfNewStyle(NewStyle):
pass
Podczas gdy klasa podstawowa w starym stylu wygląda tak:
class OldStyle():
pass
A klasa dla dzieci w starym stylu wygląda następująco:
class OldStyleSubclass(OldStyle):
pass
Widać, że klasa podstawowa Old Style nie dziedziczy po żadnej innej klasie, jednak klasy Old Style mogą oczywiście dziedziczyć po sobie. Dziedziczenie po obiekcie gwarantuje, że określona funkcjonalność jest dostępna w każdej klasie Python. W Python 2.2 wprowadzono nowe klasy stylów
object
nie jest aż tak mylące, a tak naprawdę jest dość standardowe. Smalltalk ma klasę root o nazwie Object
i metaklasę root o nazwie Class
. Dlaczego? Ponieważ, podobnie jak Dog
klasa dla psów, Object
jest klasą dla przedmiotów i Class
klasą dla klas. Java, C #, ObjC, Ruby i większość innych opartych na klasach języków OO, które ludzie używają dzisiaj i którzy mają klasę root, używają różnych odmian Object
jako nazwy, nie tylko Pythona.
Tak, to jest historyczne . Bez tego tworzy klasę w starym stylu.
Jeśli używasz obiektu type()
w starym stylu, dostajesz po prostu „instancję”. Na obiekcie w nowym stylu dostajesz jego klasę.
type()
z klas w starym stylu, zamiast „pisz” dostajesz „classobj”.
Składnia instrukcji tworzenia klasy:
class <ClassName>(superclass):
#code follows
W przypadku braku innych superklas, które konkretnie chcesz dziedziczyć, superclass
zawsze powinno być object
, co jest rdzeniem wszystkich klas w Pythonie.
object
jest technicznie głównym źródłem klas „nowego stylu” w Pythonie. Ale dziś klasy w nowym stylu są tak dobre, jak jedyny styl zajęć.
Ale jeśli nie użyjesz tego słowa wprost object
podczas tworzenia klas, to jak wspomniano inni, Python 3.x domyślnie dziedziczy po object
nadklasie. Ale chyba jawne jest zawsze lepsze niż niejawne (piekło)