En Python, comment créer une sous-classe à partir d'une superclasse?
En Python, comment créer une sous-classe à partir d'une superclasse?
Réponses:
# Initialize using Parent
#
class MySubClass(MySuperClass):
def __init__(self):
MySuperClass.__init__(self)
Ou, encore mieux, l'utilisation de la fonction intégrée de Python super()
(voir la documentation Python 2 / Python 3 pour cela) peut être une méthode légèrement meilleure pour appeler le parent pour l'initialisation:
# Better initialize using Parent (less redundant).
#
class MySubClassBetter(MySuperClass):
def __init__(self):
super(MySubClassBetter, self).__init__()
Ou, exactement la même chose que juste ci-dessus, sauf en utilisant la forme d'argument zéro de super()
, qui ne fonctionne que dans une définition de classe:
class MySubClassBetter(MySuperClass):
def __init__(self):
super().__init__()
super
, en particulier pour les nouveaux programmeurs Python (par exemple, Lutz). Je l'évite.
super
est si vous ne comprenez pas les différences entre la façon dont super
fonctionne en Python et comment super
/ parent
fonctionne dans d'autres langages. Certes, ce n'est pas évident pour les personnes venant d'autres langues, mais je ne conclurais pas que cela le qualifie de "mise en garde". Il fait le travail. Cela fonctionne simplement différemment. Lisez simplement ce qu'il fait réellement en Python avant de vous plaindre d'obtenir des résultats auxquels vous ne vous attendiez pas.
Un petit exemple héroïque:
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 section sur l'héritage dans la documentation python l'explique plus en détail
__init__
méthode que si vous souhaitez y ajouter du code, sinon la méthode init originale est utilisée de toute façon (bien que cela vaille la peine d'être mentionné et que ce soit un code parfaitement valide)
Dans les réponses ci-dessus, le super
est initialisé sans aucun argument (mot-clé). Cependant, vous aimeriez souvent faire cela, ainsi que transmettre vos propres arguments «personnalisés». Voici un exemple qui illustre ce cas d'utilisation:
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
Il s'agit d'une sous-classe list
dont, une fois initialisée, se trie immédiatement dans la direction spécifiée par l' reverse
argument mot - clé, comme l'illustrent les tests suivants:
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__])
Grâce à la transmission de *args
à super
, la liste peut être initialisée et remplie d'éléments au lieu d'être uniquement vide. (Notez qu'il reverse
s'agit d'un argument de mot-clé uniquement conformément à PEP 3102 ).
Il existe un autre moyen de créer dynamiquement des sous-classes en python avec une fonction type()
:
SubClass = type('SubClass', (BaseClass,), {'set_x': set_x}) # Methods can be set, including __init__()
Vous souhaitez généralement utiliser cette méthode lorsque vous travaillez avec des métaclasses. Lorsque vous souhaitez effectuer des automatisations de niveau inférieur, cela modifie la façon dont python crée une classe. Vous n'aurez probablement jamais besoin de le faire de cette manière, mais lorsque vous le ferez, vous saurez déjà ce que vous faites.
Tu utilises:
class DerivedClassName(BaseClassName):
Pour plus de détails, consultez la documentation Python, section 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())