Reputation: 6329
I have seen cls().__init__()
used in a classmethod, but it seems that the code could have used a simple cls()
instead. As in:
class SomeCrazyClass:
@classmethod
def newclass(cls):
return cls().__init__()
@classmethod
def newclass2(cls):
return cls()
Is this just a poor coding style choice or is there a practical use of cls().__init__()
in some situation?
Upvotes: 0
Views: 671
Reputation: 250941
The difference between cls().__init__()
and cls()
is that former calls the __init__
on instance twice and hence will return None
and the latter will return the actual instance.
But an imaginary scenario to of calling __init__
again can be used in lazy initialization of a class or may be some other use-cases as well.
For example in the below code the instance variables are loaded only on the first access of an attribute:
def init(cls, real_init):
def wrapped(self, *args, **kwargs):
cls.__init__ = real_init
return wrapped
class A(object):
def __new__(cls, *args, **kwargs):
cls.__init__ = init(cls, cls.__init__)
instance = object.__new__(cls)
return instance
def __getattr__(self, attr):
expected_attrs = ('a', 'b')
if attr in expected_attrs:
self.__init__(range(10000), range(1000))
return object.__getattribute__(self, attr)
def __init__(self, a, b):
print('inside __init__')
self.a = sum(a)
self.b = sum(b)
Demo:
>>> a = A()
>>> a.__dict__
{}
>>> a.a, a.b
inside __init__
(49995000, 499500)
>>> a.__dict__
{'a': 49995000, 'b': 499500}
>>> a = A()
>>> a.__init__(range(10**5), range(10**4))
inside __init__
>>> a.a, a.b
(4999950000, 49995000)
We can now also return a value from __init__
now which is usually not possible.
Upvotes: 1