2024-04-26 14:43:13 发布
网友
我见过在类方法中使用cls().__init__(),但代码似乎可以使用简单的cls()。例如:
cls().__init__()
cls()
class SomeCrazyClass: @classmethod def newclass(cls): return cls().__init__() @classmethod def newclass2(cls): return cls()
这只是一个糟糕的编码风格选择,还是在某些情况下有cls().__init__()的实际使用?你知道吗
cls().__init__()和cls()的区别在于前者调用实例上的__init__两次,因此将返回None,后者将返回实际实例。你知道吗
__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__返回一个通常不可能的值。你知道吗
cls().__init__()
和cls()
的区别在于前者调用实例上的__init__
两次,因此将返回None
,后者将返回实际实例。你知道吗但是,再次调用
__init__
的想象场景可以用于类的延迟初始化,也可以是其他一些用例。你知道吗例如,在下面的代码中,实例变量仅在第一次访问属性时加载:
演示:
我们现在也可以从
__init__
返回一个通常不可能的值。你知道吗相关问题 更多 >
编程相关推荐