Подтвердить что ты не робот

Определение класса реферирования в python

Есть ли способ ссылаться на имя класса из объявления класса? следует следующий пример:

class Plan(SiloBase):
    cost = DataField(int)
    start = DataField(System.DateTime)
    name = DataField(str)
    items = DataCollection(int)
    subPlan = ReferenceField(Plan)

У меня есть метакласс, который читает эту информацию и выполняет некоторую настройку, а базовый класс реализует некоторые общие вещи. я хотел бы иметь возможность создавать такие рекурсивные определения, как это, но пока в моих экспериментах я не смог добиться желаемого эффекта, обычно сталкиваясь с ошибкой "План не определен". Я понимаю, что происходит, имя класса не входит в класс внутри класса.

4b9b3361

Ответ 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, относящийся к классу.