Python: Wie erstelle ich eine Unterklasse aus einer Oberklasse?

85

Wie erstellt man in Python eine Unterklasse aus einer Oberklasse?

dave.j.lott
quelle
3
Beachten Sie, dass Python die Art und Weise geändert hat, wie Sie Unterklassen erstellen. Es gibt also zwei Möglichkeiten, dies zu tun, und sie werden nicht gemischt. Beim Mischen wird eine Fehlermeldung angezeigt. Lesen Sie diesen Beitrag, um den Unterschied zu sehen: stackoverflow.com/questions/1713038/…
Mark Lakata

Antworten:

88
# Initialize using Parent
#
class MySubClass(MySuperClass):
    def __init__(self):
        MySuperClass.__init__(self)

Oder, noch besser, die Verwendung der in Python integrierten Funktion super()(siehe Python 2 / Python 3- Dokumentation) ist möglicherweise eine etwas bessere Methode, um das übergeordnete Element zur Initialisierung aufzurufen:

# Better initialize using Parent (less redundant).
#
class MySubClassBetter(MySuperClass):
    def __init__(self):
        super(MySubClassBetter, self).__init__()

Oder genau das Gleiche wie oben, außer dass die Nullargumentform von verwendet wird super(), die nur innerhalb einer Klassendefinition funktioniert:

class MySubClassBetter(MySuperClass):
    def __init__(self):
        super().__init__()
thompsongunner
quelle
6
OTOH, einige Leute warnen davor super, insbesondere für neue Python-Programmierer (z. B. Lutz). Ich vermeide es.
Eric
6
Der einzige Grund , zu vermeiden super, wenn Sie die Unterschiede zwischen dem, wie nicht verstehen , superfunktioniert in Python, und wie super/ parentarbeitet in anderen Sprachen. Zugegeben, dies ist für Leute aus anderen Sprachen nicht offensichtlich, aber ich würde nicht schlussfolgern, dass dies es als etwas qualifiziert, vor dem man "warnen" sollte. Es funktioniert . Es funktioniert einfach anders. Lesen Sie einfach, was es in Python tatsächlich tut, bevor Sie sich über Ergebnisse beschweren, die Sie nicht erwartet haben.
TheAtomicOption
3
Was ist der Unterschied zwischen den beiden?
Tiwtiw
64

Ein heldenhaftes kleines Beispiel:

class SuperHero(object): #superclass, inherits from default object
    def getName(self):
        raise NotImplementedError #you want to override this on the child classes

class SuperMan(SuperHero): #subclass, inherits from SuperHero
    def getName(self):
        return "Clark Kent"

class SuperManII(SuperHero): #another subclass
    def getName(self):
       return "Clark Kent, Jr."

if __name__ == "__main__":
    sm = SuperMan()
    print sm.getName()
    sm2 = SuperManII()
    print sm2.getName()
ewall
quelle
37
class MySubClass(MySuperClass):
    def __init__(self):
        MySuperClass.__init__(self)

        # <the rest of your custom initialization code goes here>

Der Abschnitt zur Vererbung in der Python-Dokumentation erläutert dies ausführlicher

Bryan Oakley
quelle
5
Sie müssen diese __init__Methode nur definieren, wenn Sie weiteren Code hinzufügen möchten, andernfalls wird die ursprüngliche Init-Methode trotzdem verwendet (obwohl es erwähnenswert ist und ein vollkommen gültiger Code ist)
dbr
2
Ich denke, die Frage war vage genug, um anzunehmen, dass möglicherweise weiterer Code hinzugefügt wird. Es ist besser, zu viele Informationen als nicht genug bereitzustellen und eine andere Frage zu stellen, wenn das OP sie implementiert. :)
Matt Dewey
15
class Class1(object):
    pass

class Class2(Class1):
    pass

Klasse2 ist eine Unterklasse von Klasse1

workmad3
quelle
Cool. Dies ist, wonach ich eigentlich gesucht habe, dh eine Unterklasse ohne Erweiterung / Überschreibungen des Super.
BuvinJ
9

In den obigen Antworten wird das superohne (Schlüsselwort-) Argumente initialisiert. Oft möchten Sie dies jedoch tun und einige eigene „benutzerdefinierte“ Argumente weitergeben. Hier ist ein Beispiel, das diesen Anwendungsfall veranschaulicht:

class SortedList(list):
    def __init__(self, *args, reverse=False, **kwargs):
        super().__init__(*args, **kwargs)       # Initialize the super class
        self.reverse = reverse
        self.sort(reverse=self.reverse)         # Do additional things with the custom keyword arguments

Dies ist eine Unterklasse list, die sich beim Initialisieren sofort in die durch das reverseSchlüsselwortargument angegebene Richtung sortiert , wie die folgenden Tests veranschaulichen:

import pytest

def test_1():
    assert SortedList([5, 2, 3]) == [2, 3, 5]

def test_2():
    SortedList([5, 2, 3], reverse=True) == [5, 3, 2]

def test_3():
    with pytest.raises(TypeError):
        sorted_list = SortedList([5, 2, 3], True)   # This doesn't work because 'reverse' must be passed as a keyword argument

if __name__ == "__main__":
    pytest.main([__file__])

Dank der Weitergabe von *argsan superkann die Liste initialisiert und mit Elementen gefüllt werden, anstatt nur leer zu sein. (Beachten Sie, dass dies reverseein reines Schlüsselwortargument gemäß PEP 3102 ist. )

Kurt Peek
quelle
4

Es gibt eine andere Möglichkeit, Unterklassen in Python mit einer Funktion dynamisch zu erstellen type():

SubClass = type('SubClass', (BaseClass,), {'set_x': set_x})  # Methods can be set, including __init__()

Normalerweise möchten Sie diese Methode verwenden, wenn Sie mit Metaklassen arbeiten. Wenn Sie einige Automatisierungen auf niedrigerer Ebene ausführen möchten, ändert dies die Art und Weise, wie Python Klassen erstellt. Höchstwahrscheinlich müssen Sie dies niemals auf diese Weise tun, aber wenn Sie dies tun, wissen Sie bereits, was Sie tun.

Pol
quelle
3
class Subclass (SuperClass):
      # Subclass stuff here
Wernsey
quelle
3

Sie nutzen:

class DerivedClassName(BaseClassName):

Weitere Informationen finden Sie in den Python-Dokumenten, Abschnitt 9.5 .

Reed Copsey
quelle
2
class Mammal(object): 
#mammal stuff

class Dog(Mammal): 
#doggie stuff
Chris Ballance
quelle
1
class BankAccount:

  def __init__(self, balance=0):
    self.balance = int(balance)

  def checkBalance(self): ## Checking opening balance....
    return self.balance

  def deposit(self, deposit_amount=1000): ## takes in cash deposit amount and updates the balance accordingly.
    self.deposit_amount = deposit_amount
    self.balance += deposit_amount
    return self.balance

  def withdraw(self, withdraw_amount=500): ## takes in cash withdrawal amount and updates the balance accordingly
    if self.balance < withdraw_amount: ## if amount is greater than balance return `"invalid transaction"`
        return 'invalid transaction'
    else:
      self.balance -= withdraw_amount
      return self.balance


class MinimumBalanceAccount(BankAccount): #subclass MinimumBalanceAccount of the BankAccount class

    def __init__(self,balance=0, minimum_balance=500):
        BankAccount.__init__(self, balance=0)
        self.minimum_balance = minimum_balance
        self.balance = balance - minimum_balance
        #print "Subclass MinimumBalanceAccount of the BankAccount class created!"

    def MinimumBalance(self):
        return self.minimum_balance

c = BankAccount()
print(c.deposit(50))
print(c.withdraw(10))

b = MinimumBalanceAccount(100, 50)
print(b.deposit(50))
print(b.withdraw(10))
print(b.MinimumBalance())
Antiomic
quelle
5
Diese Antwort wäre hilfreicher, wenn Sie eine Erklärung
hinzufügen
4
Obwohl dieser Code zur Lösung des Problems beitragen kann, erklärt er nicht, warum und / oder wie er die Frage beantwortet. Die Bereitstellung dieses zusätzlichen Kontextes würde den langfristigen Bildungswert erheblich verbessern. Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung hinzuzufügen, einschließlich der Einschränkungen und Annahmen.
Toby Speight
2
Während dieses Code-Snippet die Frage lösen kann, hilft eine Erklärung wirklich dabei, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen.
Andreas
0

Die Unterklasse in Python erfolgt wie folgt:

class WindowElement:
    def print(self):
        pass

class Button(WindowElement):
    def print(self):
        pass

Hier ist ein Tutorial über Python, das auch Klassen und Unterklassen enthält.

dmeister
quelle