Wie erstellt man in Python eine Unterklasse aus einer Oberklasse?
Wie erstellt man in Python eine Unterklasse aus einer Oberklasse?
Antworten:
# 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__()
super
, insbesondere für neue Python-Programmierer (z. B. Lutz). Ich vermeide es.
super
, wenn Sie die Unterschiede zwischen dem, wie nicht verstehen , super
funktioniert in Python, und wie super
/ parent
arbeitet 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.
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()
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
__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)
In den obigen Antworten wird das super
ohne (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 reverse
Schlü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 *args
an super
kann die Liste initialisiert und mit Elementen gefüllt werden, anstatt nur leer zu sein. (Beachten Sie, dass dies reverse
ein reines Schlüsselwortargument gemäß PEP 3102 ist. )
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.
Sie nutzen:
class DerivedClassName(BaseClassName):
Weitere Informationen finden Sie in den Python-Dokumenten, Abschnitt 9.5 .
class Mammal(object):
#mammal stuff
class Dog(Mammal):
#doggie stuff
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())