En Python, ¿cómo se hace una subclase a partir de una superclase?
En Python, ¿cómo se hace una subclase a partir de una superclase?
Respuestas:
# Initialize using Parent
#
class MySubClass(MySuperClass):
def __init__(self):
MySuperClass.__init__(self)
O, mejor aún, el uso de la función incorporada de Python super()
(consulte la documentación de Python 2 / Python 3 ) puede ser un método ligeramente mejor para llamar al padre para la inicialización:
# Better initialize using Parent (less redundant).
#
class MySubClassBetter(MySuperClass):
def __init__(self):
super(MySubClassBetter, self).__init__()
O, exactamente lo mismo que antes, excepto que usa la forma de argumento cero de super()
, que solo funciona dentro de una definición de clase:
class MySubClassBetter(MySuperClass):
def __init__(self):
super().__init__()
super
, especialmente para los nuevos programadores de Python (por ejemplo, Lutz). Yo lo evito.
super
es si no comprende las diferencias entre cómo super
funciona en Python y cómo funciona super
/ parent
en otros lenguajes. Es cierto que esto no es obvio para las personas que provienen de otros idiomas, pero no concluiría que eso lo califica como algo para "advertir". Se hace el trabajo. Simplemente funciona de manera diferente. Simplemente lea sobre lo que realmente hace en Python antes de quejarse de obtener resultados que no esperaba.
Un pequeño ejemplo heroico:
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 sección sobre herencia en la documentación de Python lo explica con más detalle
__init__
método si desea agregarle más código, de lo contrario, el método init original se usa de todos modos (aunque vale la pena mencionarlo y es un código perfectamente válido)
En las respuestas anteriores, super
se inicializa sin ningún argumento (palabra clave). Sin embargo, a menudo le gustaría hacer eso, así como transmitir algunos de sus propios argumentos "personalizados". Aquí hay un ejemplo que ilustra este caso de 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
Esta es una subclase de la list
cual, cuando se inicializa, se ordena inmediatamente en la dirección especificada por el reverse
argumento de la palabra clave, como lo ilustran las siguientes pruebas:
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__])
Gracias al paso de *args
a super
, la lista se puede inicializar y completar con elementos en lugar de solo estar vacía. (Tenga en cuenta que reverse
es un argumento de solo palabras clave de acuerdo con PEP 3102 ).
Hay otra forma de crear subclases en python dinámicamente con una función type()
:
SubClass = type('SubClass', (BaseClass,), {'set_x': set_x}) # Methods can be set, including __init__()
Por lo general, desea utilizar este método cuando trabaje con metaclases. Cuando desea hacer algunas automatizaciones de nivel inferior, eso altera la forma en que Python crea la clase. Lo más probable es que nunca necesite hacerlo de esta manera, pero cuando lo haga, ya sabrá lo que está haciendo.
Tu usas:
class DerivedClassName(BaseClassName):
Para obtener más detalles, consulte los documentos de Python, sección 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())