from - python inheritance super




Python-Klassenvererbungsproblem (3)

Ich spiele mit der Vererbung der Python-Klasse und stieß auf ein Problem, bei dem das geerbte __init__ nicht ausgeführt wird, wenn es von der Unterklasse (Code unten) aufgerufen wird. Das Ergebnis von Active Python ist:

>>> start
Tom Sneed
Sue Ann
Traceback (most recent call last):
  File "C:\Python26\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 312, <br>in RunScript
    exec codeObject in __main__.__dict__
  File "C:\temp\classtest.py", line 22, in <module>
    print y.get_emp()
  File "C:\temp\classtest.py", line 16, in get_emp
    return self.FirstName + ' ' + 'abc'
AttributeError: Employee instance has no attribute 'FirstName'

Hier ist der Code

class Person():
    AnotherName = 'Sue Ann'
    def __init__(self):
        self.FirstName = 'Tom'
        self.LastName = 'Sneed'

    def get_name(self):
        return self.FirstName + ' ' + self.LastName

class Employee(Person):
    def __init__(self):
        self.empnum = 'abc123'

    def get_emp(self):
        print self.AnotherName
        return self.FirstName + ' ' + 'abc'

x = Person()
y = Employee()
print 'start'
print x.get_name()
print y.get_emp()

Drei Dinge:

  1. Sie müssen den Konstruktor explizit aufrufen. Es wird nicht automatisch wie in C ++ aufgerufen
  2. Verwenden Sie eine vom Objekt geerbte neue Stilklasse
  3. Verwenden Sie bei einer neuen Stilklasse die verfügbare super () -Methode

Das wird so aussehen:

class Person(object):
    AnotherName = 'Sue Ann'
    def __init__(self):
        super(Person, self).__init__()
        self.FirstName = 'Tom'
        self.LastName = 'Sneed'

    def get_name(self):
        return self.FirstName + ' ' + self.LastName

class Employee(Person):
    def __init__(self):
        super(Employee, self).__init__()
        self.empnum = 'abc123'

    def get_emp(self):
        print self.AnotherName
        return self.FirstName + ' ' + 'abc'

Es wird empfohlen, super zu verwenden, da es auch nur einmal in mehreren Vererbungsfällen korrekt mit aufrufenden Konstruktoren umgehen wird (solange jede Klasse im Vererbungsdiagramm auch super verwendet). Es ist auch ein Platz weniger, den Sie ändern müssen, wenn / wenn Sie ändern, was eine Klasse geerbt wird (z. B. Sie eine Basisklasse ausfiltern und die Ableitung ändern und müssen sich keine Sorgen machen, dass Ihre Klassen die falschen Eltern aufrufen Konstruktoren). Auch an der MI-Front benötigen Sie nur einen Superaufruf, um alle Konstruktoren der Basisklasse korrekt aufzurufen.


Mitarbeiter muss explizit das __init__ des Elterns (nicht init) aufrufen:

 class Employee(Person):  
    def __init__(self):  
         Person.__init__(self)  
         self.empnum = 'abc123'  

Anstatt super(class, instance) Muster warum nicht einfach super(instance) als die Klasse ist immer instance.__class__ ?

Gibt es bestimmte Fälle, in denen es keine instance.__class__ ?





inheritance