"Should I do this or not, this is a separate discussion :)"
Please keep this in mind.
But this can be done - when the class instance is created, not only the syntax is similar to a method call - with the name of the class object, followed by the y bracket - the class itself (which is a Python object), as the called object.
Calling an object in Python calls the __call__ magic method in its class. Therefore, creating an instance of the class, it calls the __call__ method in its metaclass.
What is inside this __call__ method in a standard metaclass (which is a "type") is roughly equivalent:
def __call__(cls, *args, **kw): self = cls.__new__(cls, *args, **kw) cls.__init__(self, *args, **kw) return self
So, if you write a metaclass, overriding __call__ and suppressing the __init__ call in them, it will not be called at all:
class Meta(type): def __call__(cls, *args, **kw): return cls.__new__(cls, *args, **kw) class NoInit(object): __metaclass__ = Meta def __init__(self): print "Hello!" NoInit()
If you just want to avoid that subwords have __init__ instead of not calling it, you can make a much simpler metaclass that will simply raise an exception when creating an instance of the class:
class Meta(type): def __new__(metacls, name, bases, dct): if "__init__" in dct: raise NameError("Classes in this hierarchy should not have an __init__ method") return type.__new__(metacls, name, bases, dct)