Odpowiedź na to pytanie (choć prosta) jest dość trudna do znalezienia. Googling, takie jak „klasa bazowa obiektów python” lub podobne, zawiera strony i strony samouczków na temat programowania obiektowego. Upvoting, ponieważ jest to pierwszy link, który doprowadził mnie do wyszukiwanych haseł „obiekty Python w starym lub nowym stylu”
ogromnie superormanalny
Odpowiedzi:
763
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 .
Historia Python 2.x:
W Pythonie 2.x (od wersji 2.2) istnieją dwa style klas w zależności od obecności lub nieobecności objectjako klasy podstawowej:
klasy „klasyczne” : nie mają objectjako klasy podstawowej:
>>>classClassicSpam:# no base class...pass>>>ClassicSpam.__bases__()
„nowe” klasy stylów : mają, bezpośrednio lub pośrednio (np. dziedziczą po typie wbudowanym ), objectjako klasę podstawową:
>>>classNewSpam(object):# directly inherit from object...pass>>>NewSpam.__bases__(<type 'object'>,)>>>classIntSpam(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 selfjako pierwszego argumentu.
właściwości z 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ć.
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.
Historia Python 3.x:
W Pythonie 3 rzeczy są uproszczone. Istnieją tylko klasy w nowym stylu (zwane po prostu klasami), więc jedyną różnicą w dodawaniu objectjest wymaganie wpisania kolejnych 8 znaków. To:
classClassicSpam:pass
jest całkowicie równoważne (oprócz ich nazwy :-) z tym:
classNewSpam(object):pass
i do tego:
classSpam():pass
Wszystkie mają objectw sobie __bases__.
>>>[object in cls.__bases__ for cls in{Spam,NewSpam,ClassicSpam}][True,True,True]
Co powinieneś zrobić?
W Python 2: zawsze dziedzicz po objectjawnie . Zdobądź profity.
W Pythonie 3: dziedzicz, objectjeś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.
„w zależności od obecności lub braku wbudowanego typu jako klasy bazowej” => w rzeczywistości nie chodzi o „brak lub obecność wbudowanego typu jako klasy bazowej”, ale o to, czy klasa dziedziczy - bezpośrednio lub pośrednio - od object. IIRC był moment, w którym nie wszystkie wbudowane typy zostały przeniesione do klas nowego stylu.
bruno desthuilliers
@brunodesthuilliers Mam wrażenie, że wszystkie wbudowane typy odziedziczyły 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.
Dimitris Fasarakis Hilliard
Szczerze mówiąc (por. „IIRC” w moim poprzednim komentarzu) nie jestem w 101% pewien co do tego punktu (czy wszystkie typy wbudowane zostały już przekonwertowane na klasy w nowym stylu, gdy wprowadzono klasy w nowym stylu) - może po prostu jestem prosty źle, lub mogło to dotyczyć tylko niektórych standardowych typów bibliotek (ale nie wbudowanych). Ale myślę, że lepiej jest wyjaśnić, że to, co czyni klasę nowego stylu, ma objectswoje podstawy.
bruno desthuilliers
7
szkoda, że stackoverflow robi tylko upvote = upvote + 1 dla tych rodzajów odpowiedzi, chciałbym móc zrobić upvote + = N
PirateApp
1
staticmethodi classmethoddziała dobrze nawet na lekcjach w starym stylu. propertySorta 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ą).
ShadowRanger
540
Python 3
class MyClass(object): = Klasa w nowym stylu
class MyClass:= Klasa w nowym stylu (domyślnie dziedziczy po object)
Python 2
class MyClass(object): = Klasa w nowym stylu
class MyClass:= KLASA STYLU
Objaśnienie :
Podczas definiowania klas podstawowych w Pythonie 3.x możesz usunąć objectdefinicję. 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.
„Definiując klasy podstawowe w Pythonie 3.x, możesz usunąć obiekt z definicji. Może to jednak otworzyć drzwi dla poważnie trudnego do śledzenia problemu…” Jakie problemy masz na myśli?
Aidis,
6
@Aidis: Myślę, że mają na myśli, że kod działający zarówno na Py2, jak i Py3 byłby odpowiedni na Py3, ale zostałby zepsuty na Py2, jeśli opiera się na funkcjach klasy w nowym stylu. Osobiście, jeśli piszę taki kod, pomijam jawne dziedziczenie i po prostu umieszczam __metaclass__ = typena górze modułu (po from __future__ import absolute_import, division, print_functionwierszu :-)); 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.
ShadowRanger
400
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(), @propertyi deskryptorów. Zobacz ten artykuł, aby uzyskać dobry opis tego, czym jest nowa klasa stylu.
+1 to. Zauważ, że w Pythonie 3 nie ma klas starego stylu, więc musisz dziedziczyć tylko objectw Pythonie 2.
9
To nie jest prawdziwa odpowiedź. po prostu podaje odniesienia do innych artykułów. Myślę, że odpowiedź Yarina powinna zostać zaakceptowana jako odpowiedź na to pytanie.
alwbtc
2
@alwbtc: Ta odpowiedź też ma coś nowego. Na przykład wzmianka o „super ()” doprowadziła mnie do innego ważnego [tutaj] ( stackoverflow.com/questions/576169/… ).
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 objectklasie lub innej klasie, która odziedziczyła po object:
classNewStyle(object):pass
Innym przykładem jest:
classAnotherExampleOfNewStyle(NewStyle):pass
Podczas gdy klasa podstawowa w starym stylu wygląda tak:
classOldStyle():pass
A klasa dla dzieci w starym stylu wygląda następująco:
classOldStyleSubclass(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
Wywołanie klasy root objectnie jest aż tak mylące, a tak naprawdę jest dość standardowe. Smalltalk ma klasę root o nazwie Objecti metaklasę root o nazwie Class. Dlaczego? Ponieważ, podobnie jak Dogklasa dla psów, Objectjest klasą dla przedmiotów i Classklasą 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 Objectjako nazwy, nie tylko Pythona.
abarnert
30
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ę.
Ponadto, jeśli korzystasz type()z klas w starym stylu, zamiast „pisz” dostajesz „classobj”.
Joel Sjögren
7
Składnia instrukcji tworzenia klasy:
class<ClassName>(superclass):#code follows
W przypadku braku innych superklas, które konkretnie chcesz dziedziczyć, superclasszawsze powinno być object, co jest rdzeniem wszystkich klas w Pythonie.
objectjest 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 objectpodczas tworzenia klas, to jak wspomniano inni, Python 3.x domyślnie dziedziczy po objectnadklasie. Ale chyba jawne jest zawsze lepsze niż niejawne (piekło)
Odpowiedzi:
W Pythonie 3, oprócz kompatybilności między Pythonem 2 i 3, nie ma powodu . W Python 2 wiele powodów .
Historia Python 2.x:
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:„nowe” klasy stylów : mają, bezpośrednio lub pośrednio (np. dziedziczą po typie wbudowanym ),
object
jako klasę podstawową: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 argumentuself
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.
Historia Python 3.x:
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:jest całkowicie równoważne (oprócz ich nazwy :-) z tym:
i do tego:
Wszystkie mają
object
w sobie__bases__
.Co powinieneś zrobić?
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.źródło
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
iclassmethod
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 poobject
)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.
źródło
__metaclass__ = type
na górze modułu (pofrom __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?
źródło
object
w Pythonie 2.Historia z Dowiedz się Python na własnej skórze :
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 poobject
:Innym przykładem jest:
Podczas gdy klasa podstawowa w starym stylu wygląda tak:
A klasa dla dzieci w starym stylu wygląda następująco:
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
źródło
object
nie jest aż tak mylące, a tak naprawdę jest dość standardowe. Smalltalk ma klasę root o nazwieObject
i metaklasę root o nazwieClass
. Dlaczego? Ponieważ, podobnie jakDog
klasa dla psów,Object
jest klasą dla przedmiotów iClass
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 odmianObject
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ę.źródło
type()
z klas w starym stylu, zamiast „pisz” dostajesz „classobj”.Składnia instrukcji tworzenia klasy:
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 poobject
nadklasie. Ale chyba jawne jest zawsze lepsze niż niejawne (piekło)Odniesienie
źródło