Как инициализировать классы (не экземпляры) в Python? - PullRequest
13 голосов
/ 31 мая 2011

Я хочу объединить ограничения из текущего и унаследованного классов только после загрузки класса (не для объекта!).

class Domain(Validatable):

    constraints = {...}

Для этого я определил метод _initialize_class_not_instance, который должен вызываться один раз для каждого класса:

class Validatable:

    @classmethod
    def _initialize_class_not_instance(cls):
        # merge constraints from derived class and base classes
        pass

    __class__._initialize_class_not_instance() # doesn't work
    # Validatable._merge_constraints() # doesn't work too

Проблема в том, что __class__ не существует в этом контексте и Validatable тоже не определено. Но я хочу избежать того, что пользователь моего API должен явно вызывать метод initialize или должен использовать дополнительный декоратор класса.

Есть идеи, как инициализировать класс?

Ответы [ 2 ]

17 голосов
/ 31 мая 2011

Использовать метакласс.

class MetaClass(type):
  def __init__(cls, name, bases, d):
    type.__init__(cls, name, bases, d)
    cls.foo = 42

class MyClass(object):
  __metaclass__ = MetaClass

print MyClass.foo
2 голосов
/ 31 мая 2011

Я закончил с декоратором класса и без наследования.Этот декоратор объединяет ограничения текущего и унаследованного классов и переопределяет метод __init__:

def validatable(cls):

    # merge constraints from derived class and base classes here ...

    original_init = cls.__init__
    def init_to_insert(self, *args, **keywords):
        self.errors = {}
        original_init(self, *args, **keywords)   
    cls.__init__ = init_to_insert
    return cls

Это ключ для моего решения, поскольку декоратор должен изменить класс (объединение ограничений и вставка методов) и экземпляры.

...