我在类方法中看到cls().__init__()
,但似乎代码可能使用了简单的cls()
。如:
class SomeCrazyClass:
@classmethod
def newclass(cls):
return cls().__init__()
@classmethod
def newclass2(cls):
return cls()
这只是一个糟糕的编码风格选择,还是在某些情况下是cls().__init__()
的实际用途?
答案 0 :(得分:1)
cls().__init__()
和cls()
之间的区别在于前者在实例上调用__init__
两次,因此将返回None
,后者将返回实际实例。
但是,再次调用__init__
的假想场景可用于类的延迟初始化,也可能是其他一些用例。
例如,在下面的代码中,实例变量仅在第一次访问属性时加载:
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)
<强>演示:强>
>>> 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)
我们现在也可以从__init__
返回一个通常不可能的值。