¿Hay alguna forma de definir una función que pueda agregar, en algún momento posterior del programa, nuevos atributos a un método __init__ ya existente? Por ejemplo, a continuación creé una clase para un árbol genealógico. Cada instancia crearía una raíz.

class FamilyTree:
    def __init__(self,rootObj):
        self.key = rootObj

Quiero que cada nueva instancia raíz tenga la capacidad de tener un número específico de atributos secundarios: Por ejemplo:

self.child1 = 'B'
self.child2 = 'C'
self.child3 = 'D'

Dado que cada nueva instancia raíz puede tener varios hijos, ¿cómo puedo agregar de manera variable nuevos atributos al método __init__?

1
NoPayn 12 may. 2016 a las 07:41

4 respuestas

La mejor respuesta

Una posible forma de automatizar esto es la siguiente:

class FamilyTree:
    def __init__(self,rootObj, child_names=None):
        self.key = rootObj
        if child_names is not None:
            # child_names is a list of child attributes values
            for i, child in enumerate(child_names):
                setattr(self, 'child{0}'.format(i), child)
            setattr(self, 'child_nbr', len(child_names))

    def add_child(self, *child_names)
        for name in child_names:
            self.child_nbr += 1
            setattr(self, 'child{0}'.format(self.child_nbr), name)

Uso:

>>> f=FamilyTree('Family1', ['B', 'C', 'D'])
>>> print(f.child1, f.child2, f.child3)
>>> i = 0
>>> while i < f.child_nbr:
>>>     print getattr(f, 'child{0}'.format(i+1))
>>> f.add_child('E')
>>> print(f.child4)
>>> f.add_child('F', 'G')
>>> print(f.child5, f.child6) 
0
DhiaTN 12 may. 2016 a las 07:07

Tal vez entiendo esto mal, pero no agrega atributos al método ' init ', agrega atributos a la instancia de la clase. 'self' se refiere a la instancia de la clase. Para agregar atributos durante el tiempo de ejecución a una clase, mira el ejemplo de Abhra. Para agregar atributos a una instancia específica de una clase, mira aquí (lo siento Abhra, robó tu ejemplo):

class FamilyTree:
    def __init__(self,rootObj):
        self.key = rootObj



child1='B'
child2='C'
child3='D'

objold=FamilyTree('keyold')

objold.child1=child1
objold.child2=child2
objold.child3=child3


objnew=FamilyTree('keynew')

print objnew.key, objnew.child1, objnew.child2, objnew.child3
print objold.key, objold.child1, objold.child2, objold.child3
'''
keynew AttributeError: 'FamilyTree' object has no attribute 'child1' (same error for the others)
keyold B C D
'''
0
Matthias Schreiber 12 may. 2016 a las 06:34

Supongo que lo que realmente (debería) querer es un list de niños:

class FamilyTree:

    def __init__(self, rootObj):
        self.key = rootObj
        self.children = []

    def add_children(*new_children)
        self.children.extend(new_children)

Ahora puede usar el método add_children para agregar cualquier número de hijos a la lista a la vez, o simplemente puede acceder directamente a la lista de miembros de la instancia children también:

tree = FamilyTree("whatever a rootObj is...")

tree.add_children("Alice", "Bob", "Claudia", "Dave")
tree.children.append("Eva")
tree.children += ["Fred", "Gina", "Herbert"]

print(tree.children)
# Output: ["Alice", "Bob", "Claudia", "Dave", "Eva", "Fred", "Gina", "Herbert"]
2
Byte Commander 12 may. 2016 a las 06:50
class FamilyTree:
    def __init__(self,rootObj):
        self.key = rootObj



child1='B'
child2='C'
child3='D'

objold=FamilyTree('keyold')

FamilyTree.child1=child1
FamilyTree.child2=child2
FamilyTree.child3=child3


objnew=FamilyTree('keynew')

print objnew.key,objnew.child1,objnew.child2,objnew.child3
print objold.key,objold.child1,objold.child2,objold.child3
'''
keynew B C D
keyold B C D
'''
0
Abhra 12 may. 2016 a las 04:57