Possible to prevent init from being called?

That's quite doable, but I don't think you should. Tell the users how to use your class and they should obey. Also, if someone is subclassing he should know how to call the parent's initialization method.

As a proof of concept, here's how it can be done with metaclasses (Python 2.x syntax):

>>> class WhoMovedMyInit(object):
        class __metaclass__(type):
            def __init__(self, *args, **kw):
                super(type,self).__init__(*args, **kw)
                if self.__init__ is not WhoMovedMyInit.__init__:
                    raise Exception('Dude, I told not to override my __init__')


>>> class IAmOk(WhoMovedMyInit):
        pass

>>> class Lol(WhoMovedMyInit):
        def __init__(self):
            pass

Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    class Lol(WhoMovedMyInit):
  File "<pyshell#31>", line 6, in __init__
    raise Exception('Dude, I told not to override my __init__')
Exception: Dude, I told not to override my __init__

You can also replace the subclass __init__ method to one which warns the user or raises an error on "runtime".


" Whether or not I should or need to do it is a separate discussion :)"

Please, keep that in mind.

But it can be done - when a class is instantiated, not only the syntax is just like a method call - with the class object name followed y a parenthesis - the class itself (which is a Python object), is called - as a callable object.

Calling an object in Python invokes the __call__ magic method in its class. Therefore, instantiating a class, invokes the __call__ method on its metaclass.

What is inside this __call__ method in the standard metaclass (which is "type") is roughly equivalent to:

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 suppress the call to __init__ in these, it won't 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 want just to avoid that sublcasses have __init__ instead of not calling it, you can do a much simpler metaclass that would just raise an exception at class instantiation time:

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)

Most of these answers are outdated.

This can be easily done since python 3.6. It was defined in PEP487.

class Base:
    def __init_subclass__(cls):
        if Base.__init__ is not cls.__init__:
            raise Exception(f'Do not override {cls}.__init__')

class Good(Base):
    pass

class Bad(Base):
    def __init__(self):
        pass

Good() # No problem
Bad()  # Raises Exception