1130 Stimmen

Was ist der Unterschied zwischen alten und neuen Klassen in Python?

Was ist der Unterschied zwischen alten und neuen Klassen in Python? Wann sollte ich die eine oder die andere verwenden?

625voto

Mark Cidade Punkte 95914

Von Klassen im neuen Stil und klassische Klassen :

Bis zu Python 2.1 waren die Klassen im alten Stil die einzige Möglichkeit, die dem Benutzer zur Verfügung stand.

Das Konzept der Klasse (im alten Stil) hat nichts mit dem Konzept des Typs zu tun: Wenn x eine Instanz einer Klasse alten Stils ist, dann x.__class__ bezeichnet die Klasse der x aber type(x) ist immer <type 'instance'> .

Dies spiegelt die Tatsache wider, dass alle Instanzen des alten Stils, unabhängig von ihrer Klasse, mit einem einzigen eingebauten Typ implementiert werden, der Instanz.

In Python 2.2 wurden Klassen im neuen Stil eingeführt, um die Konzepte von Klasse und Typ zu vereinheitlichen . Eine New-Style-Klasse ist einfach ein benutzerdefinierter Typ, nicht mehr und nicht weniger.

Wenn x eine Instanz einer New-Style-Klasse ist, dann type(x) ist typischerweise dasselbe wie x.__class__ (obwohl dies nicht garantiert ist - ein Klasseninstanz im neuen Stil darf den Wert überschreiben, der für x.__class__ ).

Die Hauptmotivation für die Einführung von Klassen im neuen Stil besteht darin, ein einheitliches Objektmodell mit einem vollständigen Metamodell bereitzustellen .

Es hat auch eine Reihe von unmittelbaren Vorteilen, wie die Möglichkeit, die meisten die meisten eingebauten Typen zu subklassifizieren, oder die Einführung von "Deskriptoren", die berechnete Eigenschaften ermöglichen.

Aus Kompatibilitätsgründen sind die Klassen standardmäßig noch im alten Stil gehalten .

New-Style-Klassen werden durch Angabe einer anderen New-Style-Klasse (d. h. eines Typs) als übergeordnete Klasse oder des "Top-Level-Typ"-Objekts, wenn keine andere Elternklasse benötigt wird.

Das Verhalten der Klassen des neuen Stils unterscheidet sich von dem der Klassen des alten Stils Klassen in einer Reihe von wichtigen Details, zusätzlich zu der Frage, welcher Typ zurückgibt.

Einige dieser Änderungen sind grundlegend für das neue Objektmodell, wie die Art und Weise, wie spezielle Methoden aufgerufen werden. Andere sind "Korrekturen", die nicht aus Kompatibilitätsgründen nicht implementiert werden konnten, wie die Methode Auflösungsreihenfolge im Falle von Mehrfachvererbung.

Python 3 hat nur Klassen im neuen Stil .

Unabhängig davon, ob Sie eine Unterklasse von object oder nicht, Klassen sind neuartig in Python 3.

339voto

Mark Harrison Punkte 281807

Erklärungstechnisch:

New-Style-Klassen erben von Objekt oder von einer anderen Klasse des neuen Stils.

class NewStyleClass(object):
    pass

class AnotherNewStyleClass(NewStyleClass):
    pass

Klassen im alten Stil nicht.

class OldStyleClass():
    pass

Python 3 Hinweis:

Python 3 unterstützt keine Klassen im alten Stil, so dass jede der oben genannten Formen zu einer Klasse im neuen Stil führt.

246voto

Wichtige Verhaltensänderungen zwischen alten und neuen Stilklassen

  • super hinzugefügt.
  • MRO geändert (siehe unten)
  • Deskriptoren hinzugefügt.
  • neue Stilklassenobjekte können nur dann ausgelöst werden, wenn sie von Exception (Beispiel unten)
  • __slots__ hinzugefügt.

MRO (Method Resolution Order) geändert

Es wurde bereits in anderen Antworten erwähnt, aber hier ein konkretes Beispiel für den Unterschied zwischen der klassischen MRO und der C3 MRO (die in den neuen Stilklassen verwendet wird).

Die Frage ist die Reihenfolge, in der bei der Mehrfachvererbung nach Attributen (zu denen Methoden und Mitgliedsvariablen gehören) gesucht wird.

Klassische Klassen eine Tiefensuche von links nach rechts durchführen. Bei der ersten Übereinstimmung wird angehalten. Sie haben nicht die __mro__ 属性を持つ。

class C: i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass

assert C12().i == 0
assert C21().i == 2

try:
    C12.__mro__
except AttributeError:
    pass
else:
    assert False

Klassen im neuen Stil Die MRO ist komplizierter in einem einzigen englischen Satz zusammenzufassen. Sie wird im Detail erklärt ici . Eine ihrer Eigenschaften ist, dass eine Basisklasse erst dann gesucht wird, wenn alle ihre abgeleiteten Klassen gesucht wurden. Sie haben die __mro__ Attribut, das die Suchreihenfolge anzeigt.

class C(object): i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass

assert C12().i == 2
assert C21().i == 2

assert C12.__mro__ == (C12, C1, C2, C, object)
assert C21.__mro__ == (C21, C2, C1, C, object)

Neue Stilklassenobjekte können nur dann erzeugt werden, wenn sie von Exception

Um Python 2.5 herum konnten viele Klassen erhöht werden, und um Python 2.6 herum wurde dies entfernt. In Python 2.7.3:

# OK, old:
class Old: pass
try:
    raise Old()
except Old:
    pass
else:
    assert False

# TypeError, new not derived from `Exception`.
class New(object): pass
try:
    raise New()
except TypeError:
    pass
else:
    assert False

# OK, derived from `Exception`.
class New(Exception): pass
try:
    raise New()
except New:
    pass
else:
    assert False

# `'str'` is a new style object, so you can't raise it:
try:
    raise 'str'
except TypeError:
    pass
else:
    assert False

41voto

xioxox Punkte 2375

Klassen im alten Stil sind immer noch geringfügig schneller bei der Suche nach Attributen. Dies ist in der Regel nicht wichtig, kann aber in leistungsempfindlichem Python-2.x-Code nützlich sein:

In \[3\]: class A:
   ...:     def \_\_init\_\_(self):
   ...:         self.a = 'hi there'
   ...:

In \[4\]: class B(object):
   ...:     def \_\_init\_\_(self):
   ...:         self.a = 'hi there'
   ...:

In \[6\]: aobj = A()
In \[7\]: bobj = B()

In \[8\]: %timeit aobj.a
10000000 loops, best of 3: 78.7 ns per loop

In \[10\]: %timeit bobj.a
10000000 loops, best of 3: 86.9 ns per loop

40voto

Xiao Hanyu Punkte 1316

Guido hat geschrieben Die Insider-Geschichte über New-Style-Klassen ein wirklich großartiger Artikel über New-Style- und Old-Style-Klassen in Python.

Python 3 hat nur die Klasse new-style. Selbst wenn Sie eine 'old-style Klasse' schreiben, ist diese implizit von object .

Die Klassen des neuen Stils verfügen über einige fortgeschrittene Funktionen, die in den Klassen des alten Stils fehlen, wie z. B. super die neue C3 mro einige magische Methoden, usw.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X