Die Antwort auf diese Frage (obwohl einfach) ist ziemlich schwer zu finden. Wenn Sie Dinge wie "Python Object Base Class" oder ähnliches googeln, werden Seiten und Seiten mit Tutorials zur objektorientierten Programmierung angezeigt. Upvoting, weil dies der erste Link ist, der mich zu den Suchbegriffen "alte oder neue Python-Objekte" führte
überlegener
Antworten:
764
Gibt es einen Grund, von einer Klassendeklaration zu erben object?
In Python 3 gibt es außer der Kompatibilität zwischen Python 2 und 3 keinen Grund . In Python 2 viele Gründe .
Python 2.x Geschichte:
In Python 2.x (ab 2.2) gibt es zwei Arten von Klassen, abhängig von der Anwesenheit oder Abwesenheit objecteiner Basisklasse:
"klassische" Stilklassen: Sie haben keine objectBasisklasse:
>>>classClassicSpam:# no base class...pass>>>ClassicSpam.__bases__()
"neue" Stilklassen: Sie haben direkt oder indirekt (z. B. von einem integrierten Typ geerbt ) objecteine Basisklasse:
>>>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'>,)
Ohne Zweifel möchten Sie beim Schreiben einer Klasse immer Klassen neuen Stils wählen. Die Vorteile sind zahlreich, um einige davon aufzulisten:
classmethod: Eine Methode, die die Klasse als implizites Argument anstelle der Instanz empfängt.
staticmethod: Eine Methode, die das implizite Argument nicht selfals erstes Argument empfängt .
Eigenschaften mit property: Erstellen Sie Funktionen zum Verwalten des Abrufens, Festlegens und Löschens eines Attributs.
__slots__: Spart den Speicherverbrauch einer Klasse und führt auch zu einem schnelleren Attributzugriff. Natürlich gibt es Einschränkungen .
Die __new__statische Methode: Mit dieser Option können Sie anpassen, wie neue Klasseninstanzen erstellt werden.
Method Resolution Order (MRO) : In welcher Reihenfolge werden die Basisklassen einer Klasse durchsucht, wenn versucht wird, die aufzurufende Methode aufzulösen.
Wenn Sie nicht erben object, vergessen Sie diese. Eine ausführlichere Beschreibung der vorherigen Aufzählungspunkte sowie anderer Vorteile "neuer" Stilklassen finden Sie hier .
Einer der Nachteile von Klassen neuen Stils ist, dass die Klasse selbst mehr Speicher beansprucht. Wenn Sie jedoch nicht viele Klassenobjekte erstellen, bezweifle ich, dass dies ein Problem ist, und es ist ein negativer Untergang in einem Meer von Positiven.
Python 3.x Geschichte:
In Python 3 werden die Dinge vereinfacht. Es gibt nur Klassen neuen Stils (einfach als Klassen bezeichnet). Der einzige Unterschied beim Hinzufügen objectbesteht darin, dass Sie 8 weitere Zeichen eingeben müssen. Diese:
classClassicSpam:pass
ist völlig gleichwertig (abgesehen von ihrem Namen :-) dazu:
classNewSpam(object):pass
und dazu:
classSpam():pass
Alle haben objectin ihrem __bases__.
>>>[object in cls.__bases__ for cls in{Spam,NewSpam,ClassicSpam}][True,True,True]
Also, was solltest du tun?
In Python 2: immer objectexplizit von erben . Holen Sie sich die Vorteile.
In Python 3: Erben von, objectwenn Sie Code schreiben, der versucht, Python-unabhängig zu sein, das heißt, er muss sowohl in Python 2 als auch in Python 3 funktionieren. Andernfalls macht es keinen Unterschied, da Python ihn für Sie einfügt hinter den Kulissen.
"abhängig vom Vorhandensein oder Fehlen eines eingebauten Typs als Basisklasse" => eigentlich geht es nicht um "Fehlen oder Vorhandensein eines eingebauten Typs als Basisklasse", sondern darum, ob die Klasse - direkt oder indirekt - von erbt object. IIRC Es gab einen Zeitpunkt, an dem noch nicht alle eingebauten Typen auf Klassen neuen Stils portiert wurden.
Bruno Desthuilliers
@brunodesthuilliers Mein Eindruck war, dass alle eingebauten Typen von geerbt haben object. Ich habe Python 2.2.3 in der Nähe und nach einer kurzen Überprüfung konnte ich keinen Täter finden, aber ich werde die Antwort später umformulieren, um es klarer zu machen. Wäre interessiert, wenn Sie ein Beispiel finden könnten, meine Neugier ist geweckt.
Dimitris Fasarakis Hilliard
Ehrlich gesagt (vgl. Das "IIRC" in meinem vorherigen Kommentar) bin ich mir in diesem Punkt nicht zu 101% sicher (ob alle eingebauten Typen bereits bei Einführung neuer Klassen in Klassen neuen Stils konvertiert wurden) - ich bin vielleicht einfach falsch, oder dies hat möglicherweise nur einige der Standardtypen der Bibliothek (aber nicht die eingebauten) betroffen. Aber ich denke, es sollte besser sein zu klären, was eine Klasse neuen Stils objectin ihren Basen hat.
Bruno Desthuilliers
7
Schade, dass Stackoverflow nur Upvote = Upvote + 1 für diese Art von Antworten macht. Ich wünschte, ich könnte Upvote machen + = N
PirateApp
1
staticmethodund classmethodfunktionieren auch in alten Klassen einwandfrei. propertysorta funktioniert zum Lesen in Klassen alten Stils, es kann jedoch keine Schreibvorgänge abfangen (wenn Sie also dem Namen zuweisen, erhält die Instanz ein Attribut des angegebenen Namens, das die Eigenschaft schattiert). Beachten Sie auch, dass es bei __slots__der Verbesserung der Attributzugriffsgeschwindigkeit hauptsächlich darum geht, den Verlust durch den Zugriff auf Klassenattribute neuen Stils rückgängig zu machen. Dies ist also kein Verkaufsargument für Klassen neuen Stils (die Speichereinsparungen sind jedoch ein Verkaufsargument).
ShadowRanger
540
Python 3
class MyClass(object): = Klasse neuen Stils
class MyClass:= Klasse neuen Stils (erbt implizit von object)
Python 2
class MyClass(object): = Klasse neuen Stils
class MyClass:= ALTE STILKLASSE
Erklärung :
Wenn Sie Basisklassen in Python 3.x definieren, dürfen Sie die objectaus der Definition entfernen. Dies kann jedoch die Tür für ein ernsthaft schwer zu verfolgendes Problem öffnen…
Python hat in Python 2.2 Klassen neuen Stils eingeführt, und mittlerweile sind Klassen alten Stils wirklich ziemlich alt. Die Diskussion über Klassen alten Stils ist in den 2.x-Dokumenten vergraben und in den 3.x-Dokumenten nicht vorhanden.
Das Problem ist, die Syntax für alten Stil Klassen in Python 2.x ist das gleiche wie die alternative Syntax für die neuen Stil - Klassen in Python 3.x . Python 2.x wird immer noch sehr häufig verwendet (z. B. GAE, Web2Py), und jeder Code (oder Codierer), der unbeabsichtigt Klassendefinitionen im 3.x-Stil in 2.x-Code einfügt, wird zu einigen ernsthaft veralteten Basisobjekten führen. Und weil Klassen im alten Stil nicht auf jedermanns Radar stehen, werden sie wahrscheinlich nicht wissen, was sie getroffen hat.
Also buchstabieren Sie es einfach auf lange Sicht und sparen Sie einigen 2.x-Entwicklern die Tränen.
"Wenn Sie Basisklassen in Python 3.x definieren, dürfen Sie das Objekt aus der Definition entfernen. Dies kann jedoch die Tür für ein ernsthaft schwer zu verfolgendes Problem öffnen ..." Auf welche Probleme beziehen Sie sich?
Aidis
6
@Aidis: Ich denke, sie bedeuten, dass Code, der sowohl auf Py2 als auch auf Py3 ausgeführt wird, auf Py3 in Ordnung wäre, auf Py2 jedoch nicht funktioniert, wenn er auf neuen Klassenfunktionen basiert. Wenn ich persönlich solchen Code schreibe, lasse ich die explizite Vererbung weg und setze sie einfach __metaclass__ = typeoben in das Modul (nach der from __future__ import absolute_import, division, print_functionZeile :-)). Es ist ein Kompatibilitäts-Hack in Py2, der alle nachfolgend definierten Klassen im Modul standardmäßig neu gestaltet. In Py3 wird er vollständig ignoriert (nur eine zufällige globale Variable, die herumsteht), sodass er harmlos ist.
ShadowRanger
400
Ja, dies ist ein Objekt im neuen Stil. Es war eine in Python2.2 eingeführte Funktion.
Neue Art - Objekte haben ein anderes Objektmodell klassische Objekte, und einige Dinge nicht richtig mit altem Stil Objekten, zum Beispiel, arbeiten super(), @propertyund Deskriptoren. In diesem Artikel finden Sie eine gute Beschreibung einer neuen Stilklasse.
+1 Dies. Beachten Sie, dass Klassen im alten Stil in Python 3 nicht mehr vorhanden sind, sodass Sie nur noch objectin Python 2 erben müssen .
9
Dies ist keine echte Antwort. ı verweist nur auf andere Artikel. Ich denke, Yarins Antwort sollte als Antwort auf diese Frage akzeptiert werden.
Alwbtc
2
@alwbtc: Diese Antwort hat auch etwas Neues. Zum Beispiel führte mich die Erwähnung von "super ()" zu einem anderen wichtigen [hier] ( stackoverflow.com/questions/576169/… ).
Pythons ursprüngliche Wiedergabe einer Klasse wurde in vielerlei Hinsicht gebrochen. Als dieser Fehler erkannt wurde, war es bereits zu spät und sie mussten ihn unterstützen. Um das Problem zu beheben, brauchten sie einen "neuen Klassen" -Stil, damit die "alten Klassen" weiter funktionieren, aber Sie können die neue, korrektere Version verwenden.
Sie beschlossen, ein Wort "Objekt" in Kleinbuchstaben als "Klasse" zu verwenden, von der Sie erben, um eine Klasse zu erstellen. Es ist verwirrend, aber eine Klasse erbt von der Klasse "Objekt", um eine Klasse zu erstellen, aber es ist kein Objekt, es ist wirklich eine Klasse, aber vergessen Sie nicht, vom Objekt zu erben.
Nur um Sie wissen zu lassen, was der Unterschied zwischen Klassen neuen Stils und Klassen alten Stils ist, erben Klassen neuen Stils immer von objectKlassen oder von einer anderen Klasse, die geerbt hat von object:
classNewStyle(object):pass
Ein weiteres Beispiel ist:
classAnotherExampleOfNewStyle(NewStyle):pass
Während eine Basisklasse im alten Stil so aussieht:
classOldStyle():pass
Und eine Kinderklasse im alten Stil sieht so aus:
classOldStyleSubclass(OldStyle):pass
Sie können sehen, dass eine Old Style-Basisklasse von keiner anderen Klasse erbt. Old Style-Klassen können jedoch natürlich voneinander erben. Das Erben vom Objekt garantiert, dass bestimmte Funktionen in jeder Python-Klasse verfügbar sind. In Python 2.2 wurden neue Stilklassen eingeführt
Das Aufrufen der Root-Klasse objectist nicht allzu verwirrend, und tatsächlich ist es ziemlich normal. Smalltalk hat eine Root-Klasse mit dem Namen Objectund eine Root-Metaklasse mit dem Namen Class. Warum? Denn genau wie Dogeine Klasse für Hunde Objectist sie eine Klasse für Objekte und Classeine Klasse für Klassen. Java, C #, ObjC, Ruby und die meisten anderen klassenbasierten OO-Sprachen, die heutzutage verwendet werden und eine Root-Klasse haben, verwenden eine Variation des ObjectNamens, nicht nur Python.
Abarnert
30
Ja, es ist historisch . Ohne sie entsteht eine Klasse im alten Stil.
Wenn Sie type()ein Objekt im alten Stil verwenden, erhalten Sie nur "Instanz". Auf einem Objekt neuen Stils erhalten Sie dessen Klasse.
Wenn Sie type()eine Klasse im alten Stil verwenden, erhalten Sie außerdem "classobj" anstelle von "type".
Joel Sjögren
7
Die Syntax der Anweisung zur Klassenerstellung:
class<ClassName>(superclass):#code follows
Wenn keine anderen Oberklassen vorhanden sind, von denen Sie speziell erben möchten, superclasssollte dies immer der Fall sein object, der die Wurzel aller Klassen in Python darstellt.
objectist technisch gesehen die Wurzel von "New-Style" -Klassen in Python. Aber die Klassen im neuen Stil sind heute so gut wie der einzige Klassenstil.
Wenn Sie das Wort jedoch objectbeim Erstellen von Klassen nicht explizit verwenden , erbt Python 3.x, wie bereits erwähnt, implizit von der objectOberklasse. Aber ich denke explizit ist immer besser als implizit (Hölle)
Antworten:
In Python 3 gibt es außer der Kompatibilität zwischen Python 2 und 3 keinen Grund . In Python 2 viele Gründe .
Python 2.x Geschichte:
In Python 2.x (ab 2.2) gibt es zwei Arten von Klassen, abhängig von der Anwesenheit oder Abwesenheit
object
einer Basisklasse:"klassische" Stilklassen: Sie haben keine
object
Basisklasse:"neue" Stilklassen: Sie haben direkt oder indirekt (z. B. von einem integrierten Typ geerbt )
object
eine Basisklasse:Ohne Zweifel möchten Sie beim Schreiben einer Klasse immer Klassen neuen Stils wählen. Die Vorteile sind zahlreich, um einige davon aufzulisten:
Unterstützung für Deskriptoren . Insbesondere werden die folgenden Konstrukte mit Deskriptoren ermöglicht:
classmethod
: Eine Methode, die die Klasse als implizites Argument anstelle der Instanz empfängt.staticmethod
: Eine Methode, die das implizite Argument nichtself
als erstes Argument empfängt .property
: Erstellen Sie Funktionen zum Verwalten des Abrufens, Festlegens und Löschens eines Attributs.__slots__
: Spart den Speicherverbrauch einer Klasse und führt auch zu einem schnelleren Attributzugriff. Natürlich gibt es Einschränkungen .Die
__new__
statische Methode: Mit dieser Option können Sie anpassen, wie neue Klasseninstanzen erstellt werden.Method Resolution Order (MRO) : In welcher Reihenfolge werden die Basisklassen einer Klasse durchsucht, wenn versucht wird, die aufzurufende Methode aufzulösen.
Bezogen auf MRO,
super
Anrufe . Siehe auchsuper()
super.Wenn Sie nicht erben
object
, vergessen Sie diese. Eine ausführlichere Beschreibung der vorherigen Aufzählungspunkte sowie anderer Vorteile "neuer" Stilklassen finden Sie hier .Einer der Nachteile von Klassen neuen Stils ist, dass die Klasse selbst mehr Speicher beansprucht. Wenn Sie jedoch nicht viele Klassenobjekte erstellen, bezweifle ich, dass dies ein Problem ist, und es ist ein negativer Untergang in einem Meer von Positiven.
Python 3.x Geschichte:
In Python 3 werden die Dinge vereinfacht. Es gibt nur Klassen neuen Stils (einfach als Klassen bezeichnet). Der einzige Unterschied beim Hinzufügen
object
besteht darin, dass Sie 8 weitere Zeichen eingeben müssen. Diese:ist völlig gleichwertig (abgesehen von ihrem Namen :-) dazu:
und dazu:
Alle haben
object
in ihrem__bases__
.Also, was solltest du tun?
In Python 2: immer
object
explizit von erben . Holen Sie sich die Vorteile.In Python 3: Erben von,
object
wenn Sie Code schreiben, der versucht, Python-unabhängig zu sein, das heißt, er muss sowohl in Python 2 als auch in Python 3 funktionieren. Andernfalls macht es keinen Unterschied, da Python ihn für Sie einfügt hinter den Kulissen.quelle
object
. IIRC Es gab einen Zeitpunkt, an dem noch nicht alle eingebauten Typen auf Klassen neuen Stils portiert wurden.object
. Ich habe Python 2.2.3 in der Nähe und nach einer kurzen Überprüfung konnte ich keinen Täter finden, aber ich werde die Antwort später umformulieren, um es klarer zu machen. Wäre interessiert, wenn Sie ein Beispiel finden könnten, meine Neugier ist geweckt.object
in ihren Basen hat.staticmethod
undclassmethod
funktionieren auch in alten Klassen einwandfrei.property
sorta funktioniert zum Lesen in Klassen alten Stils, es kann jedoch keine Schreibvorgänge abfangen (wenn Sie also dem Namen zuweisen, erhält die Instanz ein Attribut des angegebenen Namens, das die Eigenschaft schattiert). Beachten Sie auch, dass es bei__slots__
der Verbesserung der Attributzugriffsgeschwindigkeit hauptsächlich darum geht, den Verlust durch den Zugriff auf Klassenattribute neuen Stils rückgängig zu machen. Dies ist also kein Verkaufsargument für Klassen neuen Stils (die Speichereinsparungen sind jedoch ein Verkaufsargument).Python 3
class MyClass(object):
= Klasse neuen Stilsclass MyClass:
= Klasse neuen Stils (erbt implizit vonobject
)Python 2
class MyClass(object):
= Klasse neuen Stilsclass MyClass:
= ALTE STILKLASSEErklärung :
Wenn Sie Basisklassen in Python 3.x definieren, dürfen Sie die
object
aus der Definition entfernen. Dies kann jedoch die Tür für ein ernsthaft schwer zu verfolgendes Problem öffnen…Python hat in Python 2.2 Klassen neuen Stils eingeführt, und mittlerweile sind Klassen alten Stils wirklich ziemlich alt. Die Diskussion über Klassen alten Stils ist in den 2.x-Dokumenten vergraben und in den 3.x-Dokumenten nicht vorhanden.
Das Problem ist, die Syntax für alten Stil Klassen in Python 2.x ist das gleiche wie die alternative Syntax für die neuen Stil - Klassen in Python 3.x . Python 2.x wird immer noch sehr häufig verwendet (z. B. GAE, Web2Py), und jeder Code (oder Codierer), der unbeabsichtigt Klassendefinitionen im 3.x-Stil in 2.x-Code einfügt, wird zu einigen ernsthaft veralteten Basisobjekten führen. Und weil Klassen im alten Stil nicht auf jedermanns Radar stehen, werden sie wahrscheinlich nicht wissen, was sie getroffen hat.
Also buchstabieren Sie es einfach auf lange Sicht und sparen Sie einigen 2.x-Entwicklern die Tränen.
quelle
__metaclass__ = type
oben in das Modul (nach derfrom __future__ import absolute_import, division, print_function
Zeile :-)). Es ist ein Kompatibilitäts-Hack in Py2, der alle nachfolgend definierten Klassen im Modul standardmäßig neu gestaltet. In Py3 wird er vollständig ignoriert (nur eine zufällige globale Variable, die herumsteht), sodass er harmlos ist.Ja, dies ist ein Objekt im neuen Stil. Es war eine in Python2.2 eingeführte Funktion.
Neue Art - Objekte haben ein anderes Objektmodell klassische Objekte, und einige Dinge nicht richtig mit altem Stil Objekten, zum Beispiel, arbeiten
super()
,@property
und Deskriptoren. In diesem Artikel finden Sie eine gute Beschreibung einer neuen Stilklasse.SO Link für eine Beschreibung der Unterschiede: Was ist der Unterschied zwischen alten und neuen Stilklassen in Python?
quelle
object
in Python 2 erben müssen .Geschichte von Learn Python auf die harte Tour :
Nur um Sie wissen zu lassen, was der Unterschied zwischen Klassen neuen Stils und Klassen alten Stils ist, erben Klassen neuen Stils immer von
object
Klassen oder von einer anderen Klasse, die geerbt hat vonobject
:Ein weiteres Beispiel ist:
Während eine Basisklasse im alten Stil so aussieht:
Und eine Kinderklasse im alten Stil sieht so aus:
Sie können sehen, dass eine Old Style-Basisklasse von keiner anderen Klasse erbt. Old Style-Klassen können jedoch natürlich voneinander erben. Das Erben vom Objekt garantiert, dass bestimmte Funktionen in jeder Python-Klasse verfügbar sind. In Python 2.2 wurden neue Stilklassen eingeführt
quelle
object
ist nicht allzu verwirrend, und tatsächlich ist es ziemlich normal. Smalltalk hat eine Root-Klasse mit dem NamenObject
und eine Root-Metaklasse mit dem NamenClass
. Warum? Denn genau wieDog
eine Klasse für HundeObject
ist sie eine Klasse für Objekte undClass
eine Klasse für Klassen. Java, C #, ObjC, Ruby und die meisten anderen klassenbasierten OO-Sprachen, die heutzutage verwendet werden und eine Root-Klasse haben, verwenden eine Variation desObject
Namens, nicht nur Python.Ja, es ist historisch . Ohne sie entsteht eine Klasse im alten Stil.
Wenn Sie
type()
ein Objekt im alten Stil verwenden, erhalten Sie nur "Instanz". Auf einem Objekt neuen Stils erhalten Sie dessen Klasse.quelle
type()
eine Klasse im alten Stil verwenden, erhalten Sie außerdem "classobj" anstelle von "type".Die Syntax der Anweisung zur Klassenerstellung:
Wenn keine anderen Oberklassen vorhanden sind, von denen Sie speziell erben möchten,
superclass
sollte dies immer der Fall seinobject
, der die Wurzel aller Klassen in Python darstellt.object
ist technisch gesehen die Wurzel von "New-Style" -Klassen in Python. Aber die Klassen im neuen Stil sind heute so gut wie der einzige Klassenstil.Wenn Sie das Wort jedoch
object
beim Erstellen von Klassen nicht explizit verwenden , erbt Python 3.x, wie bereits erwähnt, implizit von derobject
Oberklasse. Aber ich denke explizit ist immer besser als implizit (Hölle)Referenz
quelle