Определение класса реферирования в python
Есть ли способ ссылаться на имя класса из объявления класса? следует следующий пример:
class Plan(SiloBase):
cost = DataField(int)
start = DataField(System.DateTime)
name = DataField(str)
items = DataCollection(int)
subPlan = ReferenceField(Plan)
У меня есть метакласс, который читает эту информацию и выполняет некоторую настройку, а базовый класс реализует некоторые общие вещи. я хотел бы иметь возможность создавать такие рекурсивные определения, как это, но пока в моих экспериментах я не смог добиться желаемого эффекта, обычно сталкиваясь с ошибкой "План не определен". Я понимаю, что происходит, имя класса не входит в класс внутри класса.
Ответы
Ответ 1
У меня есть метакласс, который читает эту информацию и выполняет некоторую настройку
Большинство фреймворков, которые используют метаклассы, предоставляют возможность решить эту проблему. Например, Django:
subplan = ForeignKey('self')
Google App Engine:
subplan = SelfReferenceProperty()
Проблема с такими решениями, как привязка дополнительного свойства к более позднему или с использованием __new__
, заключается в том, что большинство метаклассов ORM ожидают, что свойства класса будут существовать в момент создания класса.
Ответ 2
Попробуйте следующее:
class Plan(SiloBase):
cost = DataField(int)
start = DataField(System.DateTime)
name = DataField(str)
items = DataCollection(int)
Plan.subPlan = ReferenceField(Plan)
ИЛИ используйте __new__
следующим образом:
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)
Ответ 3
Я понимаю, что происходит, имя класса не входит в сферу действия внутри класса.
Не совсем. Имя класса еще не определено при определении его содержимого (например, области).
Ответ 4
Нет, вы не можете этого сделать. Подумайте, что произойдет, если вы это сделаете:
OtherPlan = Plan
other_plan = OtherPlan()
При создании other_plan
, каково имя класса?
В любом случае, такого рода лучше всего сделать в методе __new__
, который принимает параметр cls
, относящийся к классу.