Python: Wie erstelle ich eine Unterklasse aus einer Oberklasse?


85

Wie erstellt man in Python eine Unterklasse aus einer Oberklasse?


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__()

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()

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


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


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. )


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.





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())

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.