Sklavit Sklavit - 21 days ago 6
Python Question

May __init__ be used as normal method for initialization, not as constructor?

Sometimes it looks reasonable to use

__init__
as initialization method for already existing object, i.e.:

class A():
def __init__(self, x):
self.x = x

def set_state_from_file(self, file):
x = parse_file(file)
self.__init__(x)


As alternative to this implementation I see the following:

class A():
def __init__(self, x):
self.init(x)

def init(self, x):
self.x = x

def set_state_from_file(self, file):
x = parse_file(file)
self.init(x)


It seems to me as over-complication of code. Is there any guideline on this situation?

Answer

__init__ is not a constructor. It is an initialisation method, called after the instance was already constructed for you (the actual constructor method is called __new__()).

You can always call it again from your code if you need to re-initialise, this isn't a style violation. In fact, it is used in the Python standard library; see the multiprocessing.heap.Heap() implementation for example:

def malloc(self, size):
    # return a block of right size (possibly rounded up)
    assert 0 <= size < sys.maxsize
    if os.getpid() != self._lastpid:
        self.__init__()                     # reinitialize after fork

or the threading.local implementation, which uses a context manager to defer initialisation.

There is otherwise nothing special about the __init__ method itself. It is merely automatically called by type.__call__ (after creating the instance with instance = cls.__new__(cls, *args, **kwargs), cls.__init__(instance, *args, **kwargs) is called if it is available).

Comments