stringvar - Definición de clase de autorreferencia en python
que es stringvar python (4)
¿Hay alguna forma de hacer referencia a un nombre de clase dentro de la declaración de clase? un ejemplo sigue:
class Plan(SiloBase):
cost = DataField(int)
start = DataField(System.DateTime)
name = DataField(str)
items = DataCollection(int)
subPlan = ReferenceField(Plan)
Tengo una metaclase que lee esta información y realiza alguna configuración, y la clase base implementa algunas cosas comunes de guardado. Me encantaría poder crear definiciones recursivas como esta, pero hasta ahora en mi experimentación no he podido obtener el efecto que deseo, normalmente me encuentro con un error "El plan no está definido". Entiendo lo que está sucediendo, el nombre de la clase no está dentro del alcance dentro de la clase.
Entiendo lo que está sucediendo, el nombre de la clase no está dentro del alcance dentro de la clase.
No exactamente. El nombre de la clase aún no está definido cuando se definen sus contenidos (por ejemplo, alcance).
Tengo una metaclase que lee esta información y hace algunos ajustes.
La mayoría de los marcos que usan metaclases proporcionan una manera de resolver esto. Por ejemplo, Django :
subplan = ForeignKey(''self'')
subplan = SelfReferenceProperty()
El problema con soluciones como agregar una propiedad adicional más adelante o usar __new__
es que la mayoría de las metaclases ORM esperan que las propiedades de la clase existan en el momento en que se crea la clase.
No, no puedes hacer eso. Piensa en lo que pasaría si hicieras esto:
OtherPlan = Plan
other_plan = OtherPlan()
En la instanciación de other_plan
, ¿cuál es el nombre de la clase?
De todos modos, este tipo de cosas se realiza mejor en el método __new__
, que toma un parámetro cls
que se refiere a la clase.
Prueba esto:
class Plan(SiloBase):
cost = DataField(int)
start = DataField(System.DateTime)
name = DataField(str)
items = DataCollection(int)
Plan.subPlan = ReferenceField(Plan)
O use __new__
esta manera:
class Plan(SiloBase):
def __new__(cls, *args, **kwargs):
cls.cost = DataField(int)
cls.start = DataField(System.DateTime)
cls.name = DataField(str)
cls.items = DataCollection(int)
cls.subPlan = ReferenceField(cls)
return object.__new__(cls, *args, **kwargs)