Frage

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

War es hilfreich?

Lösung

http: //docs.python .org / 2 / reference / datamodel.html # new-style-und-classic-Klassen :

  

Bis zu Python 2.1, im alten Stil Klassen der einzige Geschmack für den Benutzer verfügbar waren.

     

Das Konzept der (alten Stils) Klasse ist mit dem Begriff der Art in keinem Zusammenhang:   wenn x eine Instanz einer alten Stil-Klasse ist, dann x.__class__   bezeichnet die Klasse von x, aber type(x) ist immer <type 'instance'>.

     

Dies spiegelt die Tatsache wider, dass alle alten Stil Instanzen unabhängig   ihre Klasse wird mit einem einzigen eingebauten Typ implementiert, genannt   Beispiel.

     

New-Style-Klassen wurden in Python 2.2 eingeführt, um die Konzepte der Klasse und Typ zu vereinen.   Ein neuer Stil Klasse ist einfach ein benutzerdefinierter Typ, nicht mehr, nicht weniger.

     

Wenn x eine Instanz eines neuen Stils Klasse ist, dann ist type(x) typischerweise   die gleichen wie x.__class__ (obwohl dies nicht gewährleistet ist - ein   neuer Stil Klasseninstanz darf den Wert außer Kraft zu setzen zurückgegeben   für x.__class__).

     

Die Hauptmotivation für neuen Stil Klassen einzuführen, ist ein einheitliches Objektmodell mit einem vollständigen Meta-Modell zur Verfügung zu stellen .

     

Es hat auch eine Reihe von unmittelbaren Vorteilen, wie die Fähigkeit zu   Unterklasse die meisten integrierten Typen, oder die Einführung von „Deskriptoren“,   die es ermöglichen, berechneten Eigenschaften.

     

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

     

New-Style-Klassen werden durch die Angabe eine weitere neue Stil-Klasse erstellt   (Das heißt eine Art) als eine Elternklasse, oder das „Top-Level-Typ“, wenn kein Objekt   andere Elternteil erforderlich.

     

Das Verhalten der neuen Stils Klassen unterscheidet sich von der im alten Stil   Klassen in einer Reihe von wichtigen Details zusätzlich zu welcher Art   kehrt zurück.

     

Einige dieser Veränderungen sind von grundlegender Bedeutung für das neue Objektmodell, wie   die Art und Weise spezielle Methoden aufgerufen werden. Andere sind „fixe“ Das konnte nicht   bevor für Kompatibilitätsprobleme, wie das Verfahren durchgeführt werden   Auflösung, um im Fall von Mehrfachvererbung.

     

Python 3 hat nur neue Klassen-Stil .

     

Egal, ob Sie von object Unterklasse oder nicht, Klassen sind im neuen Stil   in Python 3.

Andere Tipps

Erklärung weise:

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

class NewStyleClass(object):
    pass

class AnotherNewStyleClass(NewStyleClass):
    pass

Old-Style-Klassen nicht.

class OldStyleClass():
    pass

Wichtige Verhaltensänderungen zwischen alten und neuen Stilklassen

  • Super hinzugefügt
  • MRO geändert (siehe unten)
  • Deskriptoren hinzugefügt
  • neuen Stil Klasse Objekte können nicht, es sei denn aus Exception (Beispiel unten)
  • abgeleitet angehoben werden
  • __slots__ hinzugefügt

MRO (Methode Resolution Order) geändert

Es wurde in anderen Antworten erwähnt, aber hier geht ein konkretes Beispiel für den Unterschied zwischen klassischen MRO und C3 MRO (in neuen Stil Klassen).

Die Frage ist die Reihenfolge, in den Attributen (zu denen auch Methoden und Variablen Mitglied) werden in Mehrfachvererbung gesucht.

Classic Klassen tun, um eine Tiefensuche von links nach rechts. Stopp auf dem ersten Spiel. Sie haben nicht das __mro__ Attribut.

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

New-Style-Klassen MRO komplizierter ist in einem englischen Satz zu synthetisieren. Es wird im Detail hier erklärt. Eine seiner Eigenschaften ist, dass eine Basisklasse wird nur einmal alle seine Abgeleitete Klassen wurden durchsucht. Sie haben das __mro__ Attribut, das die Suchreihenfolge zeigt.

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)

New Artklasse Objekte können nicht, es sei denn aus Exception

abgeleitet angehoben werden

Um Python 2.5 viele Klassen könnten erhöht werden, um Python 2.6 diese entfernt wurde. Auf 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

Old Style-Klassen sind noch geringfügig schneller für Attribut-Lookup. Dies ist in der Regel nicht wichtig, kann aber sinnvoll sein, in der Leistung empfindliche Python 2.x Code:

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

Guido hat geschrieben The Inside Story auf New-Style-Klassen , ein wirklich großer Artikel über neuen Stil und im alten Stil Klasse in Python.

Python 3 hat nur neue Stil-Klasse, auch wenn Sie eine ‚alten Stil Klasse‘ zu schreiben, es implizit aus object abgeleitet wird.

New-Style-Klassen haben einige erweiterte Funktionen fehlen in alten Stil Klassen wie super und dem neuen C3 MRO einige magische Methoden, etc.

Hier ist ein sehr praktisch, True / False Unterschied. Der einzige Unterschied zwischen den beiden Versionen des folgenden Codes ist, dass in der zweiten Version Person von Objekt erbt. Anders als dass die beiden Versionen identisch sind, aber mit unterschiedlichen Ergebnissen:

1) im alten Stil Klassen

class Person():
    _names_cache = {}
    def __init__(self,name):
        self.name = name
    def __new__(cls,name):
        return cls._names_cache.setdefault(name,object.__new__(cls,name))

ahmed1 = Person("Ahmed")
ahmed2 = Person("Ahmed")
print ahmed1 is ahmed2
print ahmed1
print ahmed2


>>> False
<__main__.Person instance at 0xb74acf8c>
<__main__.Person instance at 0xb74ac6cc>
>>>

2) new-Style-Klassen

class Person(object):
    _names_cache = {}
    def __init__(self,name):
        self.name = name
    def __new__(cls,name):
        return cls._names_cache.setdefault(name,object.__new__(cls,name))

ahmed1 = Person("Ahmed")
ahmed2 = Person("Ahmed")
print ahmed2 is ahmed1
print ahmed1
print ahmed2

>>> True
<__main__.Person object at 0xb74ac66c>
<__main__.Person object at 0xb74ac66c>
>>>

New-Style-Klassen von object erben und müssen 2.2 ab als solche in Python geschrieben werden (das heißt class Classname(object): statt class Classname:). Der Kern Änderung Typen und Klassen zu vereinen, und der nette Nebeneffekt ist, dass es Sie von integrierten Typen erben kann.

Lesen Sie descrintro für weitere Details.

New Style-Klassen verwenden super(Foo, self) wo Foo ist eine Klasse und self ist die Instanz.

  

super(type[, object-or-type])

     

Gibt ein Proxy-Objekt, dass die Delegierten Methodenaufrufe an einen Elternteil oder Geschwister Klasse des Typs. Dies ist nützlich für geerbte Methoden zugreifen, die in einer Klasse überschrieben wurden. Die Suchreihenfolge ist die gleiche wie die von getattr () verwendet, außer dass der Typ selbst übersprungen wird.

Und in Python 3.x können Sie einfach super() innerhalb einer Klasse ohne Parameter verwenden.

Oder besser gesagt, Sie sollten immer neuen Stil-Klassen verwenden, es sei denn, Sie Code haben, mit Versionen von Python arbeiten muss älter als 2.2.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top