Python继承内置enumerate类疑问:未调用父类__init__却正常运行
关于继承enumerate类未调用super().__init__仍能运行的原因
你猜的没错,就是__new__方法在暗中帮你完成了基类enumerate的初始化。
核心原因:内置迭代器类的初始化逻辑在__new__中
enumerate属于Python的内置迭代器类型,这类对象的创建和核心初始化逻辑并不在__init__方法里,而是放在__new__方法中。当你执行myenum(['a','b','c','d','e'])创建实例时:
- 因为你没有重写
myenum的__new__,Python会自动调用继承自enumerate的__new__方法; - 这个
__new__方法会接收你传入的可迭代对象,完成基类enumerate的所有初始化工作,返回一个已经就绪的实例; - 之后才会调用你重写的
__init__方法,只是在这个已初始化的实例上额外添加x_和len_两个属性,完全不影响基类的初始化流程。
验证调用顺序
你可以重写__new__方法来直观观察流程:
class myenum(enumerate): def __new__(cls, x): print("执行__new__方法,完成基类初始化") return super().__new__(cls, x) def __init__(self,x): print("执行__init__方法,添加自定义属性") self.x_ = x self.len_ = len(x) def __next__(self): out = super().__next__() print(f'Doing {out[0]} of {self.len_}') return out for ictr, key in myenum(['a','b','c','d','e']): print('Working...')
运行后会先打印执行__new__方法,完成基类初始化,再打印执行__init__方法,添加自定义属性,清晰体现了__new__先完成基类初始化的过程。
小建议
虽然当前代码能正常运行,但继承内置类时最好显式调用super().__init__(),哪怕看起来没实际作用——这会让代码更规范,也能避免Python版本迭代可能带来的兼容性问题。
内容的提问来源于stack exchange,提问作者NNN
相关产品推荐
相关产品推荐

