Gibt es einen Grund, von einer Klassendeklaration zu erben object
?
Ich habe gerade einen Code gefunden, der dies tut, und ich kann keinen guten Grund dafür finden.
class MyClass(object):
# class code follows...
Gibt es einen Grund, von einer Klassendeklaration zu erben object
?
Ich habe gerade einen Code gefunden, der dies tut, und ich kann keinen guten Grund dafür finden.
class MyClass(object):
# class code follows...
Antworten:
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 .
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:
>>> class ClassicSpam: # no base class
... pass
>>> ClassicSpam.__bases__
()
"neue" Stilklassen: Sie haben direkt oder indirekt (z. B. von einem integrierten Typ geerbt ) object
eine Basisklasse:
>>> 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'>,)
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 nicht self
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 auch super()
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.
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:
class ClassicSpam:
pass
ist völlig gleichwertig (abgesehen von ihrem Namen :-) dazu:
class NewSpam(object):
pass
und dazu:
class Spam():
pass
Alle haben object
in ihrem __bases__
.
>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]
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.
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
und classmethod
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 von object
)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.
__metaclass__ = type
oben in das Modul (nach der from __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?
object
in Python 2 erben müssen .
Geschichte von Learn Python auf die harte Tour :
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 object
Klassen oder von einer anderen Klasse, die geerbt hat von object
:
class NewStyle(object):
pass
Ein weiteres Beispiel ist:
class AnotherExampleOfNewStyle(NewStyle):
pass
Während eine Basisklasse im alten Stil so aussieht:
class OldStyle():
pass
Und eine Kinderklasse im alten Stil sieht so aus:
class OldStyleSubclass(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
object
ist nicht allzu verwirrend, und tatsächlich ist es ziemlich normal. Smalltalk hat eine Root-Klasse mit dem Namen Object
und eine Root-Metaklasse mit dem Namen Class
. Warum? Denn genau wie Dog
eine Klasse für Hunde Object
ist sie eine Klasse für Objekte und Class
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 des Object
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.
type()
eine Klasse im alten Stil verwenden, erhalten Sie außerdem "classobj" anstelle von "type".
Die Syntax der Anweisung zur Klassenerstellung:
class <ClassName>(superclass):
#code follows
Wenn keine anderen Oberklassen vorhanden sind, von denen Sie speziell erben möchten, superclass
sollte dies immer der Fall sein object
, 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 der object
Oberklasse. Aber ich denke explizit ist immer besser als implizit (Hölle)