«Должен ли я это делать или нет, это отдельное обсуждение :)»
Пожалуйста, имейте это в виду.
Но это можно сделать - когда классРеализованный, не только синтаксис похож на вызов метода - с именем объекта класса после скобки - сам класс (который является объектом Python) называется - вызываемым объектом.
Вызов объектав Python вызывает магический метод __call__
в своем классе.Следовательно, при создании экземпляра класса вызывается метод __call__
для его метакласса.
То, что находится внутри этого метода __call__
в стандартном метаклассе (который является "типом"), примерно эквивалентно:
def __call__(cls, *args, **kw):
self = cls.__new__(cls, *args, **kw)
cls.__init__(self, *args, **kw)
return self
Итак, если вы напишите метакласс, переопределяя __call__
и подавив в нем вызов __init__
, он вообще не будет вызываться:
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()
Если вы хотите простово избежание того, что у подклассов есть __init__
вместо того, чтобы не вызывать его, вы можете создать гораздо более простой метакласс, который бы просто вызывал исключение во время создания класса:
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)