Ursprünglich wollte ich diese Frage stellen , aber dann stellte ich fest, dass bereits daran gedacht wurde ...
Beim Googeln habe ich dieses Beispiel für die Erweiterung von configparser gefunden . Folgendes funktioniert mit Python 3:
$ python3
Python 3.2.3rc2 (default, Mar 21 2012, 06:59:51)
[GCC 4.6.3] on linux2
>>> from configparser import SafeConfigParser
>>> class AmritaConfigParser(SafeConfigParser):
... def __init_(self):
... super().__init__()
...
>>> cfg = AmritaConfigParser()
Aber nicht mit Python 2:
>>> class AmritaConfigParser(SafeConfigParser):
... def __init__(self):
... super(SafeConfigParser).init()
...
>>> cfg = AmritaConfigParser()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __init__
TypeError: must be type, not classob
Dann habe ich ein wenig über Python New Class vs. Old Class-Stile gelesen (z . B. hier . Und jetzt frage ich mich, ob ich Folgendes tun kann:
class MyConfigParser(ConfigParser.ConfigParser):
def Write(self, fp):
"""override the module's original write funcition"""
....
def MyWrite(self, fp):
"""Define new function and inherit all others"""
Aber sollte ich nicht init anrufen? Ist dies in Python 2 das Äquivalent:
class AmritaConfigParser(ConfigParser.SafeConfigParser):
#def __init__(self):
# super().__init__() # Python3 syntax, or rather, new style class syntax ...
#
# is this the equivalent of the above ?
def __init__(self):
ConfigParser.SafeConfigParser.__init__(self)
python
inheritance
configparser
Oz123
quelle
quelle
__init__()
in der Unterklasse definieren, wenn nur die Superklasse '__init__()
(entweder in Python 2 oder 3) aufgerufen wird. Lassen Sie stattdessen einfach die Superklasse vererben.Antworten:
super()
(ohne Argumente) wurde in Python 3 (zusammen mit__class__
) eingeführt:Das wäre also das Python 2-Äquivalent für Klassen neuen Stils:
Für Klassen im alten Stil können Sie immer Folgendes verwenden:
quelle
super(__class__)
gibtNameError: global name '__class__' is not defined
, undsuper(self.__class__)
ist ebenso falsch. Sie müssen eine Instanz als zweites Argument angeben, was darauf hindeutet, dass Sie dies tun müssensuper(self.__class__, self)
, aber das ist falsch . WennClass2
erbt vonClass1
undClass1
Anrufesuper(self.__class__, self).__init__()
,Class1
‚s__init__
wird dann selbst nennen , wenn eine Instanz instanziierenClass2
.TypeError: super() takes at least 1 argument (0 given)
beim Versuch,super(self.__class__)
Python 2 aufzurufen . (Das macht nicht viel Sinn, zeigt aber, wie viele Informationen in dieser Antwort fehlen.)__init__()
das ungebundene Superobjekt ohne Argument aufzurufen (das Sie durch Aufrufensuper(self.__class__)
mit nur einem Argument erhalten), ein gebundenes Superobjekt benötigen, dann sollte es funktionieren :super(CurrentClass, self).__init__()
. Nicht verwenden,self.__class__
da sich dies beim Aufrufen eines übergeordneten Elements immer auf dieselbe Klasse bezieht. Erstellen Sie daher eine Endlosschleife, wenn dieses übergeordnete Element dasselbe tut.__class__
(Mitglied) existiert auch in Python2 .__class__
Mitglied, sondern um den implizit erstellten lexikalischen__class__
Abschluss, der sich immer auf die aktuell definierte Klasse bezieht, die in Python2 nicht vorhanden ist.In einem einzelnen Vererbungsfall (wenn Sie nur eine Klasse unterordnen) erbt Ihre neue Klasse Methoden der Basisklasse. Dies beinhaltet
__init__
. Wenn Sie es also nicht in Ihrer Klasse definieren, erhalten Sie das von der Basis.Die Dinge werden kompliziert, wenn Sie mehrere Vererbungen einführen (Unterklassen von mehr als einer Klasse gleichzeitig). Dies liegt daran
__init__
, dass Ihre Klasse nur die erste erbt, wenn mehr als eine Basisklasse vorhanden ist .In solchen Fällen sollten Sie wirklich verwenden,
super
wenn Sie können, ich werde erklären, warum. Aber das kannst du nicht immer. Das Problem ist, dass alle Ihre Basisklassen es auch verwenden müssen (und auch ihre Basisklassen - den gesamten Baum).Wenn dies der Fall ist, funktioniert dies auch korrekt (in Python 3, aber Sie können es in Python 2 überarbeiten - es hat auch
super
):Beachten Sie, wie beide Basisklassen verwendet werden
super
, obwohl sie keine eigenen Basisklassen haben.Was
super
bedeutet, ist: Es ruft die Methode aus der nächsten Klasse in MRO (Method Resolution Order) auf. Der MRO fürC
ist :(C, A, B, object)
. Sie können druckenC.__mro__
, um es zu sehen.So
C
erbt__init__
vonA
undsuper
inA.__init__
AnrufenB.__init__
(B
folgtA
in MRO).Wenn Sie also nichts tun
C
, rufen Sie am Ende beide an, was Sie wollen.Wenn Sie nicht verwenden würden
super
, würden Sie am EndeA.__init__
(wie zuvor) erben, aber dieses Mal gibt es nichts, was Sie fordern würdeB.__init__
.Um dies zu beheben, müssen Sie Folgendes definieren
C.__init__
:Das Problem dabei ist, dass in komplizierteren MI-Bäumen
__init__
Methoden einiger Klassen möglicherweise mehrmals aufgerufen werden, während Super / MRO garantieren, dass sie nur einmal aufgerufen werden.quelle
Notice how both base classes use super even though they don't have their own base classes.
Sie haben. In py3k unterklassifiziert jede Klasse das Objekt.Kurz gesagt, sie sind gleichwertig. Lassen Sie uns eine Verlaufsansicht haben:
(1) Die Funktion sieht zunächst so aus.
(2) um Code abstrakter (und portabler) zu machen. Eine übliche Methode, um Super-Class zu erhalten, ist wie folgt erfunden:
Und die Init-Funktion kann sein:
Wenn jedoch sowohl die Klasse als auch die Instanz explizit übergeben werden müssen, wird die DRY-Regel (Don't Repeat Yourself) ein wenig verletzt.
(3) in V3. Es ist schlauer,
ist in den meisten Fällen genug. Sie können auf http://www.python.org/dev/peps/pep-3135/ verweisen.
quelle
Nur um ein einfaches und vollständiges Beispiel für Python 3 zu haben, das die meisten Leute derzeit zu verwenden scheinen.
gibt
quelle
Eine weitere Python3-Implementierung, die die Verwendung von Abstract-Klassen mit super () beinhaltet. Daran solltest du dich erinnern
hat den gleichen Effekt wie
Denken Sie daran, dass es in super () ein verstecktes 'Selbst' gibt. Das gleiche Objekt wird also an die Superklasse-Init-Methode weitergegeben, und die Attribute werden dem Objekt hinzugefügt, das es aufgerufen hat. Daher
super()
wird in übersetztPerson
und wenn Sie dann das verborgene Selbst einschließen, erhalten Sie den obigen Code frag.quelle