Warum erben Python-Klassen das Objekt?

Lesezeit: 9 Minuten

Benutzer-Avatar
tjvr

Warum erbt die folgende Klassendeklaration von object?

class MyClass(object):
    ...

  • Dadurch entsteht ein Klasse im neuen Stil.

    – SLaks

    25. Oktober 2010 um 14:20 Uhr

  • Die Antwort auf diese Frage (obwohl einfach) ist ziemlich schwer zu finden. Dinge wie “python object base class” oder ähnliches zu googeln bringt seitenweise Tutorials zur objektorientierten Programmierung. Upvoting, weil dies der erste Link ist, der mich zu den Suchbegriffen “alte vs. neue Python-Objekte” geführt hat

    – weit überlegener Mensch

    22. Dezember 2015 um 20:42 Uhr

  • Für den Teil „Suchen nach dieser Frage“ ist SymbolHound eine Option.

    – Benutzer202729

    31. Januar 2021 um 6:48 Uhr

Benutzer-Avatar
Dimitris Fasarakis Hilliard

Gibt es einen Grund, von einer Klassendeklaration zu erben? object?

In Python 3, abgesehen von der Kompatibilität zwischen Python 2 und 3, kein Grund. In Python2, viele Gründe.


Python 2.x-Geschichte:

In Python 2.x (ab 2.2) gibt es je nach Vorhandensein oder Fehlen von zwei Arten von Klassen object als Basisklasse:

  1. “klassischer Stil Klassen: Sie haben keine object als Basisklasse:

    >>> class ClassicSpam:      # no base class
    ...     pass
    >>> ClassicSpam.__bases__
    ()
    
  2. “neuer Stil Klassen: sie haben, direkt oder indirekt (zB erben von a eingebauter Typ), object als 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, wenn Sie eine Klasse schreiben, werden Sie stets für Kurse im neuen Stil gehen möchten. Die Vorteile sind zahlreich, um nur einige davon aufzuzählen:

  • Unterstützung für Deskriptoren. Konkret werden mit Deskriptoren folgende Konstrukte ermöglicht:

    1. classmethod: Eine Methode, die anstelle der Instanz die Klasse als implizites Argument erhält.
    2. staticmethod: Eine Methode, die das implizite Argument nicht erhält self als erstes Argument.
    3. Eigenschaften mit property: Erstellen Sie Funktionen zum Verwalten des Abrufens, Setzens und Löschens eines Attributs.
    4. __slots__: Spart den Speicherverbrauch einer Klasse und führt auch zu einem schnelleren Attributzugriff. Natürlich tut es das Beschränkungen auferlegen.
  • Das __new__ statische Methode: Ermöglicht es Ihnen, anzupassen, wie neue Klasseninstanzen erstellt werden.

  • Methodenauflösungsordnung (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() gilt als super.

Wenn Sie nicht von erben object, vergiss diese. Eine ausführlichere Beschreibung der vorherigen Aufzählungspunkte zusammen mit anderen Vorteilen von “neuen” Stilklassen finden Sie hier hier.

Einer der Nachteile von Klassen im neuen Stil ist, dass die Klasse selbst mehr Speicher beansprucht. Wenn Sie jedoch nicht viele Klassenobjekte erstellen, bezweifle ich, dass dies ein Problem wäre, und es ist ein negatives Versinken in einem Meer von Positiven.


Python 3.x-Geschichte:

In Python 3 sind die Dinge vereinfacht. Es gibt nur Klassen im neuen Stil (die einfach als Klassen bezeichnet werden), also der einzige Unterschied beim Hinzufügen object erfordert, dass Sie 8 weitere Zeichen eingeben. Dies:

class ClassicSpam:
    pass

ist völlig äquivalent (abgesehen von ihrem Namen 🙂 dazu:

class NewSpam(object):
     pass

und dazu:

class Spam():
    pass

Alle haben object in ihren __bases__.

>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]

Also, was sollten Sie tun?

In Python2: immer erben von object ausdrücklich. Holen Sie sich die Vorteile.

In Python3: geerbt von object Wenn Sie Code schreiben, der versucht, Python-agnostisch zu sein, muss er also sowohl in Python 2 als auch in Python 3 funktionieren. Andernfalls macht es keinen Unterschied, da Python ihn hinter den Kulissen für Sie einfügt.

  • “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 ob die Klasse direkt erbt oder indirekt – aus object. IIRC Es gab einen Zeitpunkt, an dem noch nicht alle eingebauten Typen auf neue Klassen portiert wurden.

    – bruno desthuilliers

    19. März 2018 um 15:31 Uhr

  • @brunodesthuilliers Mein Eindruck war, dass alle eingebauten Typen 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 sie klarer zu machen. Würde mich aber interessieren, ob Sie ein Beispiel finden könnten, meine Neugier ist geweckt.

    – Dimitris Fasarakis Hilliard

    20. März 2018 um 9:50 Uhr


  • Ehrlich gesagt (siehe “IIRC” in meinem vorherigen Kommentar) bin ich mir in diesem Punkt nicht 101% sicher (ob alle eingebauten Typen bereits in Klassen neuen Stils konvertiert wurden, als Klassen neuen Stils eingeführt wurden) – ich bin vielleicht einfach nur klar falsch, oder dies könnte nur einige der (aber nicht eingebauten) Typen der Standardbibliothek betroffen haben. Aber ich denke, es sollte besser klargestellt werden, was eine Klasse im neuen Stil ausmacht object in seinen Basen.

    – bruno desthuilliers

    20. März 2018 um 11:18 Uhr


  • staticmethod und classmethod funktionieren auch bei Klassen im alten Stil einwandfrei. property irgendwie arbeitet für lesen Bei Klassen im alten Stil kann es Schreibvorgänge einfach nicht abfangen (wenn Sie also den Namen zuweisen, erhält die Instanz ein Attribut des angegebenen Namens, das die Eigenschaft überschattet). Beachte das auch __slots__Bei der Verbesserung der Attributzugriffsgeschwindigkeit geht es hauptsächlich darum, den Verlust rückgängig zu machen, der durch den Zugriff auf Klassenattribute im neuen Stil entsteht, also ist es nicht wirklich ein Verkaufsargument für Klassen im neuen Stil (die Speichereinsparungen sind jedoch ein Verkaufsargument).

    – ShadowRanger

    2. April 2019 um 0:26 Uhr

Benutzer-Avatar
Yarin

Python 3

  • class MyClass(object): = Klasse im neuen Stil
  • class MyClass: = Klasse im neuen Stil (erbt implizit von object)

Python 2

  • class MyClass(object): = Klasse im neuen Stil
  • class MyClass: = OLD-STYLE-KLASSE

Erläuterung:

Beim Definieren von Basisklassen in Python 3.x dürfen Sie die object aus der Definition. Dies kann jedoch die Tür für ein ernsthaft schwer zu verfolgendes Problem öffnen …

Python hat in Python 2.2 Klassen im neuen Stil eingeführt, und inzwischen sind Klassen im alten Stil wirklich ziemlich alt. Diskussion über Klassen im alten Stil ist in den 2.x-Dokumenten begrabenund in den 3.x-Dokumenten nicht vorhanden.

Das Problem ist, Die Syntax für Klassen im alten Stil in Python 2.x ist dieselbe wie die alternative Syntax für Klassen im neuen Stil in Python 3.x. Python 2.x ist immer noch sehr weit verbreitet (z. B. GAE, Web2Py), und jeder Code (oder Codierer), der unwissentlich Klassendefinitionen im 3.x-Stil in 2.x-Code einbringt, wird mit einigen ernsthaft veralteten Basisobjekten enden. Und weil Klassen im alten Stil nicht auf dem Radar von irgendjemandem sind, werden sie wahrscheinlich nicht wissen, was sie getroffen hat.

Also buchstabieren Sie es einfach lange und ersparen Sie einigen 2.x-Entwicklern die Tränen.

  • “Wenn Sie Basisklassen in Python 3.x definieren, dürfen Sie das Objekt aus der Definition löschen. Dies kann jedoch die Tür für ein ernsthaft schwer nachzuverfolgendes Problem öffnen …” Auf welche Probleme beziehen Sie sich?

    – Aidis

    11. Dezember 2014 um 20:30 Uhr

  • @Aidis: Ich denke, sie meinen, dass Code, der sowohl auf Py2 als auch auf Py3 läuft, auf Py3 in Ordnung wäre, aber auf Py2 kaputt wäre, wenn er auf Klassenfunktionen im neuen Stil angewiesen ist. Wenn ich solchen Code schreibe, lasse ich persönlich die explizite Vererbung weg und setze einfach __metaclass__ = type am oberen Rand des Moduls (nach der from __future__ import absolute_import, division, print_function Linie 🙂 ); Es ist ein Kompatibilitäts-Hack in Py2, der alle nachfolgend definierten Klassen im Modul standardmäßig in einem neuen Stil macht, und in Py3 wird es vollständig ignoriert (nur eine zufällige globale Variable, die herumsitzt), also ist es harmlos.

    – ShadowRanger

    9. Dezember 2016 um 2:07 Uhr


  • Nun, da Python 2 veraltet ist, sie aus dem Orbit vernichten?

    – Endolith

    19. September 2020 um 17:17 Uhr

Benutzer-Avatar
Jerub

Ja, dies ist ein Objekt im „neuen Stil“. Es war eine Funktion, die in python2.2 eingeführt wurde.

Objekte im neuen Stil haben ein anderes Objektmodell als klassische Objekte, und einige Dinge funktionieren nicht richtig mit Objekten im alten Stil, z. super(), @property und Deskriptoren. Sehen Dieser Artikel für eine gute Beschreibung dessen, was eine neue Stilklasse ist.

SO-Link für eine Beschreibung der Unterschiede: Was ist der Unterschied zwischen alten und neuen Klassen in Python?

  • +1 Dies. Beachten Sie, dass Klassen im alten Stil in Python 3 verschwunden sind, sodass Sie nur von erben müssen object in Python2.

    Benutzer395760

    25. Oktober 2010 um 14:33 Uhr

  • Dies ist keine wirkliche Antwort. Ich verweise nur auf andere Artikel. Ich denke, Yarins Antwort sollte als Antwort auf diese Frage akzeptiert werden.

    – alwbtc

    1. Januar 2016 um 12:41 Uhr

  • @alwbtc: Diese Antwort hat auch etwas Neues. Zum Beispiel führte mich die Erwähnung von “super()” zu einem anderen wichtigen [here](stackoverflow.com/questions/576169/… ).

    – ViFI

    28. Juni 2016 um 21:59 Uhr

Benutzer-Avatar
Anzeigename

Geschichte ab Lernen Sie Python auf die harte Tour:

Pythons ursprüngliche Wiedergabe einer Klasse wurde in vielerlei Hinsicht beschädigt. 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 Klassenstil”, damit die “alten Klassen” weiter funktionieren, aber Sie können die neue, korrektere Version verwenden.

Sie entschieden, dass sie ein Wort “Objekt” in Kleinbuchstaben verwenden würden, um die “Klasse” zu sein, von der Sie erben, um eine Klasse zu erstellen. Es ist verwirrend, aber eine Klasse erbt von der Klasse namens “Objekt”, um eine Klasse zu erstellen, aber es ist kein Objekt, sondern eine Klasse, aber vergessen Sie nicht, von Objekt zu erben.

Nur um Sie wissen zu lassen, was der Unterschied zwischen Klassen im neuen Stil und Klassen im alten Stil ist, erben die Klassen im neuen Stil immer von object Klasse oder von einer anderen Klasse, die geerbt hat 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 untergeordnete Klasse im alten Stil sieht so aus:

class OldStyleSubclass(OldStyle):
    pass

Sie können sehen, dass eine Basisklasse im alten Stil von keiner anderen Klasse erbt, aber Klassen im alten Stil können natürlich voneinander erben. Das Erben von Objekt garantiert, dass bestimmte Funktionen in jeder Python-Klasse verfügbar sind. In Python 2.2 wurden neue Stilklassen eingeführt

Benutzer-Avatar
stricken

Ja es ist historisch. Ohne sie entsteht eine Klasse im alten Stil.

Wenn du benutzt type() Bei einem Objekt im alten Stil erhalten Sie nur “Instanz”. Bei einem Objekt neuen Stils erhalten Sie seine Klasse.

  • Auch wenn Sie verwenden type() Bei einer Klasse im alten Stil erhalten Sie “classobj” anstelle von “type”.

    – Joel Sjögren

    15. Februar 2014 um 15:31 Uhr

Benutzer-Avatar
kmario23

Die Syntax der Klassenerstellungsanweisung:

class <ClassName>(superclass):
    #code follows

In Ermangelung anderer Oberklassen, von denen Sie ausdrücklich erben möchten, ist die superclass sollte immer sein objectdie die Wurzel aller Klassen in Python ist.

object ist technisch gesehen die Wurzel von “neuen” Klassen in Python. Aber der Unterricht im neuen Stil ist heute so gut wie der einzige Unterrichtsstil.

Aber wenn Sie das Wort nicht explizit verwenden object Beim Erstellen von Klassen erbt Python 3.x, wie bereits erwähnt, implizit von der object Oberklasse. Aber ich denke, explizit ist immer besser als implizit (Hölle)

Bezug

  • Auch wenn Sie verwenden type() Bei einer Klasse im alten Stil erhalten Sie “classobj” anstelle von “type”.

    – Joel Sjögren

    15. Februar 2014 um 15:31 Uhr

1157670cookie-checkWarum erben Python-Klassen das Objekt?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy