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.

Python, Lista de niños

Quiero generar una estructura de datos padre/hijo en Python 3.8.10. [GCC 9.3.0] en linux. El código es tan simple como:

class Member(object):
    name = "xxx"
    parent = None
    children = []

    def __init__(self, name):
        object.__init__(self)
        self.name = name

    def setParent(self,p):
        self.parent = p

    def addChild(self,ch):
        self.children.append(ch)
        ch.setParent(self)

    def myRelatives(self):
        str = "Soy {0}, mi padre es {1} y mis hijos son:".format(self.name,self.parent.name if self.parent is not None else "--")
        print(str)

        for ch in self.children:
            print("   {0}".format(ch.name))


if __name__ == '__main__':
    A = Member("A")
    B = Member("B")
    C = Member("C")
    D = Member("D")

    A.addChild(B)
    B.addChild(C)
    C.addChild(D)

    A.myRelatives()
    B.myRelatives()
    C.myRelatives()
    D.myRelatives()

Esperaba:

Soy A, mi padre es -- y mis hijos son:
   B
Soy B, mi padre es A y mis hijos son:
   C
Soy C, mi padre es B y mis hijos son:
   D
Soy D, mi padre es C y mis hijos son:

Sin embargo, mi salida es:

Soy A, mi padre es -- y mis hijos son:
   B
   C
   D
Soy B, mi padre es A y mis hijos son:
   B
   C
   D
Soy C, mi padre es B y mis hijos son:
   B
   C
   D
Soy D, mi padre es C y mis hijos son:
   B
   C
   D

Parece que ‘self.children’ se utiliza como la misma variable en todas las instancias. ¿Por qué y cómo solucionarlo?

Gracias,
Bernd

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema en el código es que la lista children se define como un atributo de clase en lugar de un atributo de instancia. Esto significa que cada instancia de la clase Member tiene una referencia al mismo objeto de lista.

    Para solucionar esto, debemos definir children como un atributo de instancia dentro del método __init__(). Podemos hacer esto reemplazando la línea children = [] con self.children = [].

    Aquí está el código actualizado:

    class Member(object):
        name = "xxx"
        parent = None
    
        def __init__(self, name):
            object.__init__(self)
            self.name = name
            self.children = []
    
        def setParent(self, parent):
            self.parent = parent
    
        def addChild(self, child):
            self.children.append(child)
            child.setParent(self)
    
        def myRelatives(self):
            str = "Soy {0}, mi padre es {1} y mis hijos son:".format(self.name, self.parent.name if self.parent is not None else "--")
            print(str)
    
            for child in self.children:
                print("   {0}".format(child.name))
    
    if __name__ == '__main__':
        A = Member("A")
        B = Member("B")
        C = Member("C")
        D = Member("D")
    
        A.addChild(B)
        B.addChild(C)
        C.addChild(D)
    
        A.myRelatives()
        B.myRelatives()
        C.myRelatives()
        D.myRelatives()
    

    Esto debería dar el resultado esperado:

    Soy A, mi padre es -- y mis hijos son:
       B
    Soy B, mi padre es A y mis hijos son:
       C
    Soy C, mi padre es B y mis hijos son:
       D
    Soy D, mi padre es C y mis hijos son:
    

    ¡Espero que esto ayude!

Comments are closed.