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?
Update: There is a case when it is definitely not an alternate constructor case: unpickling. During unpickling, pickle first creates an instance and only then sets its state.
__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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With