In Python, come si crea una sottoclasse da una superclasse?
In Python, come si crea una sottoclasse da una superclasse?
Risposte:
# Initialize using Parent
#
class MySubClass(MySuperClass):
def __init__(self):
MySuperClass.__init__(self)
O, ancora meglio, l'uso della funzione incorporata di Python super()
(vedere la documentazione di Python 2 / Python 3 per questo) potrebbe essere un metodo leggermente migliore per chiamare il genitore per l'inizializzazione:
# Better initialize using Parent (less redundant).
#
class MySubClassBetter(MySuperClass):
def __init__(self):
super(MySubClassBetter, self).__init__()
Oppure, la stessa identica cosa appena sopra, tranne che usando la forma di argomento zero di super()
, che funziona solo all'interno di una definizione di classe:
class MySubClassBetter(MySuperClass):
def __init__(self):
super().__init__()
super
, specialmente per i nuovi programmatori Python (ad esempio, Lutz). Lo evito.
super
è se non capisci le differenze tra come super
funziona in Python e come super
/ parent
funziona in altri linguaggi. Certamente questo non è ovvio per le persone che provengono da altre lingue, ma non concluderei che questo lo qualifichi come qualcosa da "mettere in guardia". Si fa il lavoro. Funziona solo diversamente. Leggi cosa fa effettivamente in Python prima di lamentarti di ottenere risultati che non ti aspettavi.
Un piccolo esempio eroico:
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>
La sezione sull'ereditarietà nella documentazione di python lo spiega in maggior dettaglio
__init__
metodo se vuoi aggiungere ulteriore codice ad esso, altrimenti viene utilizzato comunque il metodo originale init (anche se vale la pena menzionarlo ed è un codice perfettamente valido)
Nelle risposte precedenti, super
viene inizializzato senza argomenti (parola chiave). Spesso, tuttavia, ti piacerebbe farlo, oltre a trasmettere alcuni tuoi argomenti "personalizzati". Ecco un esempio che illustra questo caso d'uso:
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
Questa è una sottoclasse di list
cui, una volta inizializzata, si ordina immediatamente nella direzione specificata reverse
dall'argomento della parola chiave, come illustrano i seguenti test:
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__])
Grazie al passaggio di *args
a super
, la lista può essere inizializzata e popolata con elementi invece di essere solo vuota. (Notare che reverse
è un argomento di sola parola chiave in conformità con PEP 3102 ).
C'è un altro modo per creare sottoclassi in Python dinamicamente con una funzione type()
:
SubClass = type('SubClass', (BaseClass,), {'set_x': set_x}) # Methods can be set, including __init__()
Di solito si desidera utilizzare questo metodo quando si lavora con le metaclassi. Quando vuoi fare alcune automazioni di livello inferiore, questo cambia il modo in cui python crea la classe. Molto probabilmente non avrai mai bisogno di farlo in questo modo, ma quando lo farai, saprai già cosa stai facendo.
Usate:
class DerivedClassName(BaseClassName):
Per i dettagli, vedere la documentazione di Python, sezione 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())