Herencia y Sobreescritura init en python
Estaba leyendo 'Dive Into Python' y en el capítulo sobre clases da este ejemplo:
class FileInfo(UserDict):
"store file metadata"
def __init__(self, filename=None):
UserDict.__init__(self)
self["name"] = filename
El autor entonces dice que si desea sobrescribir el método __init__
, debe llamar explícitamente al padre __init__
con los parámetros correctos.
- ¿Y si esa clase
FileInfo
tuviera más de una clase de antepasado?- ¿Tengo que llamar explícitamente a todos los métodos
__init__
de las clases antecesoras?
- ¿Tengo que llamar explícitamente a todos los métodos
- También, tengo que hacer esto a cualquier otro método I desea anular?
5 answers
El libro está un poco anticuado con respecto a las llamadas subclase-superclase. También es un poco anticuado con respecto a las clases integradas de subclases.
Se ve así hoy en día.
class FileInfo(dict):
"""store file metadata"""
def __init__(self, filename=None):
super( FileInfo, self ).__init__()
self["name"] = filename
Tenga en cuenta lo siguiente.
Podemos subclase directamente clases integradas, como
dict
,list
,tuple
, etc.La función
super
se encarga de rastrear las superclases de esta clase y llamar a las funciones en ellas apropiadamente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-15 20:49:52
En cada clase de la que necesita heredar, puede ejecutar un bucle de cada clase que necesita iniciarlo al iniciar el hijo class...an ejemplo que se puede copiar podría ser mejor entendido...
class Female_Grandparent:
def __init__(self):
self.grandma_name = 'Grandma'
class Male_Grandparent:
def __init__(self):
self.grandpa_name = 'Grandpa'
class Parent(Female_Grandparent, Male_Grandparent):
def __init__(self):
Female_Grandparent.__init__(self)
Male_Grandparent.__init__(self)
self.parent_name = 'Parent Class'
class Child(Parent):
def __init__(self):
Parent.__init__(self)
#---------------------------------------------------------------------------------------#
for cls in Parent.__bases__: # This block grabs the classes of the child
cls.__init__(self) # class (which is named 'Parent' in this case),
# and iterates through them, initiating each one.
# The result is that each parent, of each child,
# is automatically handled upon initiation of the
# dependent class. WOOT WOOT! :D
#---------------------------------------------------------------------------------------#
g = Female_Grandparent()
print g.grandma_name
p = Parent()
print p.grandma_name
child = Child()
print child.grandma_name
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-30 22:20:05
Realmente no tiene para llamar a los métodos __init__
de la(s) clase (s) base, pero normalmente quiere hacerlo porque las clases base harán algunas inicializaciones importantes allí que son necesarias para que el resto de los métodos de las clases funcionen.
Para otros métodos depende de sus intenciones. Si solo desea agregar algo al comportamiento de las clases base, querrá llamar al método clases base adicionalmente a su propio código. Si desea cambiar fundamentalmente la comportamiento, es posible que no llame al método de la clase base e implemente toda la funcionalidad directamente en la clase derivada.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-15 21:00:40
Si la clase FileInfo tiene más de una clase ancestro entonces definitivamente deberías llamar a todas sus funciones __init__ (). También deberías hacer lo mismo con la función __del__ (), que es un destructor.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-15 20:49:08
Sí, debe llamar a __init__
para cada clase padre. Lo mismo ocurre con las funciones, si está sobreescribiendo una función que existe en ambos padres.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-15 20:50:35