Python内置函数super的不便之处
先看示例代码:
class Top(object):
def foo(self):
print('Top')
class Middle(Top):
def foo(self):
print('Middle')
super(self.__class__, self).foo()
class Bottom(Middle):
pass
b = Bottom()
def foo(self):
print('Top')
class Middle(Top):
def foo(self):
print('Middle')
super(self.__class__, self).foo()
class Bottom(Middle):
pass
b = Bottom()
继续执行时如下这行代码时:
b.foo()
报RuntimeError: maximum recursion depth exceeded while calling a Python object。
看来是由于递归的关系导致Python栈溢出了(CPython的函数栈很浅,使用递归要小心)。通过traceback信息和debug日志知道,根本原因是Middle.foo被递归执行了,为什么会出现这样的错误呢?这段代码很普通嘛,只是最底层的子类想要使用中间父类的方法而已,这种场景太常见了,答案在super的机制上,super(type, object).method()会以实例object调用类型type的父类所定义的方法method。
b.foo()的方法查找顺序是:
1、查找实例本身
2、实例的类
3、父类Middle
执行到父类的foo处,此时代码中的self所指代的实例是Bottom的实例,self.__class__是Bottom,杯具就在这里了,super(self.__class__, self).foo()会反复的调用Middle.foo……
要解决这个问题很简单,老老实实用super没出现前的写法即可:
class Middle(Top):
def foo(self):
print('Middle')
Top.foo(self)
def foo(self):
print('Middle')
Top.foo(self)
如此调用目标就很明确了。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 《HelloGitHub》第 106 期
· 数据库服务器 SQL Server 版本升级公告
· 深入理解Mybatis分库分表执行原理
· 使用 Dify + LLM 构建精确任务处理应用