Reputation: 92367
I want to merge constraints from the current and inherited classes only once a class is loaded (not per object!).
class Domain(Validatable):
constraints = {...}
To do this I defined a method _initialize_class_not_instance
that should be called once for each class:
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
The problem is that __class__
doesn't exist in this context and Validatable
is not defined too. But I want to avoid, that the user of my API has to call the initialize method explicitely or has to use an additional class decorator.
Any ideas how to initialize the class?
Upvotes: 15
Views: 8008
Reputation: 92367
I ended up with a class decorator and without inheritance. This decorator merges the constraints of the current and inherited classes and overrides the __init__
method:
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
This is the key for my solution, since the decorator has to modify the class (merging constraints and inserting methods) and instances.
Upvotes: 2
Reputation: 798526
Use a metaclass.
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
Upvotes: 17