Utilizando la misma clase en la definición del atributo de la clase.
¿Cómo puedo hacer algo como esto?
class Formulario(object, metaclass=...):
pass
class Campo(object):
def __init__(self, clase_formulario_anidado=None):
self.clase_formulario_anidado = clase_formulario_anidado
class FormularioTarea(Formulario):
hijos = Campo(clase_formulario_anidado=FormularioTarea)
Rendereiza:
NameError: el nombre 'FormularioTarea' no está definido
El error ocurre en la línea que define el atributo ‘hijos’.
Utilizo atributos de clase en la función __new__
de la metaclase y no puedo moverlo a la función __init__
de la clase actual.
Mi metaclase (como en el framework de Django):
class MetaForm(type):
"""
Metaclase para extraer campos del modelo
"""
def __new__(mcs, nombre, bases, attrs):
campos_encontrados = dict()
for k, v in attrs.items():
if isinstance(v, Campo):
campos_encontrados[k] = v
attrs['campos_encontrados'] = campos_encontrados
nueva_clase = super().__new__(mcs, nombre, bases, attrs)
campos_padres = {}
for base in reversed(nueva_clase.__mro__):
# Recolecta los campos de la clase base.
if hasattr(base, 'campos_encontrados'):
campos_padres.update(base.campos_encontrados)
# Deshabilita los campos reordenados.
for attr, value in base.__dict__.items():
if value is None and attr in campos_padres:
campos_padres.pop(attr)
nueva_clase.campos_base = campos_padres
nueva_clase.campos_encontrados = campos_padres
return nueva_clase
davy.ai
Para crear una metaclase que permita la funcionalidad deseada, puedes hacer lo siguiente:
La metaclase
FormMeta
te permite crear dinámicamente un atributofields
en la clase, el cual es un diccionario de nombres de campo a los atributosnested_form_class
definidos en cadaField
. Luego, se define la clase baseForm
para instanciar cada objetoField
como un atributo en la nueva instancia de la clase. Finalmente, se define la claseTaskForm
para utilizar una cadena en lugar de una referencia real a sí misma al definir el campochildren
, lo cual permite que sea definido antes de queTaskForm
sea efectivamente definida.