es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

En Python, ¿se realiza la inicialización de las clases padre A y B al mismo tiempo en la herencia múltiple?

Tengo una pregunta sobre el proceso de instanciación de una clase hija con herencia múltiple de la clase padre A sin argumentos y de la clase padre B con argumentos de palabra clave respectivamente.

En el código a continuación, no entiendo por qué se ejecuta el método “set_kwargs()” de “ParentB” mientras se inicializa “ParentA” cuando se crea una instancia de “Child”.

(Especialmente, ¿por qué los resultados muestran “Child recibe {}”? ¿Cómo puedo evitar estos resultados?)

Cualquier ayuda sería muy apreciada.

¡Gracias!

class GrandParent:
    def __init__(self):
        print(f"{self.__class__.__name__} inicializado")

class ParentA(GrandParent):
    def __init__(self):
        super().__init__()

class ParentB(GrandParent):
    def __init__(self, **kwargs):
        super().__init__()
        self.set_kwargs(**kwargs)

    def set_kwargs(self, **kwargs):
        print(f"{self.__class__.__name__} recibe {kwargs}")
        self.content = kwargs.get('content')

class Child(ParentA, ParentB):
    def __init__(self, **kwargs):
        ParentA.__init__(self)
        ParentB.__init__(self, **kwargs)

c = Child(content = 3)

resultados:

Child inicializado
Child recibe {}
Child inicializado
Child recibe {'content': 3}
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Explicación:

    Cuando se crea una clase hija con herencia múltiple, primero buscará el método init() en la primera clase padre mencionada, que en este caso es ParentA. Por lo tanto, se llama primero al método init() de ParentA, que imprime “Child initialized”.

    A continuación, la clase hija busca el método init() en la segunda clase padre mencionada, que es ParentB. Dado que el método init() de ParentB requiere argumentos de palabras clave, no se puede llamar sin argumentos. Por lo tanto, cuando se crea la instancia Child con c = Child(content = 3), se llama al método init() de ParentB con el argumento de palabra clave “content”. Esto imprime “Child receive {‘content’: 3}”.

    Para evitar imprimir “Child receive {}” al crear una instancia de Child sin argumentos de palabras clave, puede modificar el método init() de ParentB para incluir un diccionario vacío predeterminado para kwargs:

    class ParentB(GrandParent):
        def __init__(self, **kwargs):
            super().__init__()
            self.set_kwargs(**kwargs)
    
        def set_kwargs(self, **kwargs):
            if kwargs:
                print(f"{self.__class__.__name__} recibe {kwargs}")
                self.content = kwargs.get('content')
    

    De esta manera, si no se proporcionan kwargs, la declaración if evaluará a False y se omitirá la instrucción print.

    Alternativamente, puedes modificar el método init() de la clase Child para proporcionar siempre un diccionario vacío para kwargs de ParentB:

    class Child(ParentA, ParentB):
        def __init__(self, **kwargs):
            ParentA.__init__(self)
            ParentB.__init__(self, **kwargs if kwargs else {})
    

    De esta manera, incluso si no se proporcionan kwargs, se pasa un diccionario vacío al método init() de ParentB, evitando que imprima “Child receive {}”.

Comments are closed.