2011-05-31 43 views
12

我只想在一个类加载(而不是每个对象!)时合并来自当前类和继承类的约束。如何在Python中初始化类(不是实例)?

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的用户必须明确地调用初始化方法,或者必须使用额外的类装饰器。

任何想法如何初始化类?

+0

请注意,类**是**实例,通常它们是'type'的实例,但是@Ignacio指出它们可以是'type'自定义子类的实例。 – Duncan 2011-05-31 08:01:56

回答

1

我结束了一个类装饰器,没有继承。这个装饰合并电流和继承类的约束和覆盖__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 

这是我的解决方案的关键,因为装饰有权修改类(合并约束和插入方法)和实例。

16

使用元类。

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 
+8

作为记录,在python3中,它是'MyClass(object,metaclass = MetaClass)' – ninjagecko 2011-05-31 06:28:11

+0

为什么你需要MetaClass?为什么不在“MyClass”的定义之后放置语句“MyClass.foo = 42”? – 2015-10-31 18:18:02