14

クラスがロードされたときにのみ、現在のクラスと継承されたクラスの制約をマージしたい(オブジェクトごとではありません!)。

class Domain(Validatable):

    constraints = {...}

これを行う_initialize_class_not_instanceために、クラスごとに1回呼び出す必要があるメソッドを定義しました。

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メソッドを明示的に呼び出すか、追加のクラスデコレータを使用する必要があることは避けたいと思います。

クラスを初期化する方法はありますか?

4

2 に答える 2

17

メタクラスを使用します。

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
于 2011-05-31T06:23:34.380 に答える
2

私はクラスデコレータを継承せずに終了しました。このデコレータは、現在のクラスと継承されたクラスの制約をマージし、__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

デコレータはクラス(制約のマージとメソッドの挿入)とインスタンスを変更する必要があるため、これが私のソリューションの鍵となります。

于 2011-05-31T17:12:05.577 に答える