当前位置: 首页 > news >正文

Python Cookbook-6.20 精确和安全地使用协作的超类调用

任务

你很欣赏通过内建的super 来支持的多继承的代码的协作方式,但同时你也希望能够更加简洁和精确地使用这种方式。

解决方案

一个好的方案是使用支持多继承的 mixin 类,此类使用了内省机制,且更加简洁:

import inspect
class SuperMixin(object):def super(cls,*args,**kwargs):frame = inspect.currentframe(1)self = frame.f_locals['self']methodName = frame.f_code.co_namemethod = getattr(super(cls,self), methodName, None)if inspect.ismethod(method):return method(*args,**kwargs)super = classmethod(super)

任何从 SuperMixin 派生的类都将获得一个名为 super 的魔术般的方法:在 cls 类的一个叫做 somename 的方法中调用 cls.super(args)等于是在调用 super(cls,self).somename(args)。而且,即使在方法解析顺序(Method Resolution Order,MRO)中,在 cls 类之后没有任何类定义过一个叫做 somename 的方法,这个调用也是安全的。

讨论

下面是一个用法示例:

if __name__ = '__main__'class TestBase(list,SuperMixin):#注意:myMethod并未在此定义passclass MyTest1(TestBase):def myMethod(self):print "in MyTest1"MyTest1.super()class MyTest2(TestBase):def myMethod(self):print "in MyTest2"MyTest2.super()class MyTest(MyTest1, MyTest2):def myMethod(self):print "in MyTest"MyTest.super()MyTest().myMethod()
#输出:
# in MyTest
# in MyTest1
# in MyTest2

Python 已经支持“新风格”类好些年了,作为比经典类更好的选择,新风格类也是默认的选项。经典类的存在仅仅是为了满足一些老版本 Python 向后兼容的需要,对于新代码是不推荐使用的。使用新风格类的一个优点就是,我们可以很轻松地以一种“协作”的方式调用超类的实现,而且还完全支持多继承,这应当归功于内建的super。

假设你的新风格类 cls 中有一个方法,这个方法需要先完成自己的任务然后将余下的工作委托给超类的同名方法。代码一般为:

def somename(self,*args):...some preliminary task...return super(cls,self).somename(*args)

这个做法有两个小问题:比较啰嗦,而且它依赖于超类提供了方法somename。如果你想把 cls 和其他类隔离得更开一些,从而获得更强的健壮性,可以除掉其依赖性,但代码就变得更啰嗦了:

def somename(self,*args):...some preliminary task...try:super_method = super(cls,self).somenameexcept AttributeError:return Noneelse:return super_method(*args)

而解决方案中的 mixin 类 SuperMixin 则完美解决了这两方面的问题。只要 cls 直接或间接地从 SuperMixin 派生(也可以同时从其他需要的类派生),你就能够以一种精确和健壮的方式完成任务:

def somename(self,*args):...some preliminary task...return cls.super(*args)

类方法 SuperMixin.super 依赖于一个简单的内省来获取self对象以及方法的名字,然后在内部使用内建的super和getattr 来获取超类方法,如果此方法存在的话,再安全地调用之。内省是通过 Python 标准库的方便的inspect模块实现的,这使得整个任务变得更加简单。

http://www.xdnf.cn/news/282385.html

相关文章:

  • 【AI提示词】黑天鹅模型专家
  • 从图文到声纹:DeepSeek 多模态技术的深度解析与实战应用
  • 气泡图、桑基图的绘制
  • Sway初体验
  • 微软Phi-4-reasoning技术报告解读
  • HTML基础1-元素与页面的结构
  • “链式前向星”等三种存图方式分别输出“无向无权图”的“DFS序列”
  • ABC404E 题解
  • 2025牛客五一集训派对day4
  • 纯继电器电路控制小车自动往复运动
  • (39)VTK C++开发示例 ---选择区域
  • MFiX(Multiphase Flow with Interphase eXchanges)软件介绍
  • 5块钱的无忧套餐卡可以变成流量卡吗
  • Winform(10.常用控件3)
  • ResNet改进(36):ResNeXt与ResNet的混合模型实现
  • Spring AI 实战:第十一章、Spring AI Agent之知行合一
  • 线程与进程深度解析:从fork行为到生产者-消费者模型
  • Raycaster光线投射
  • OPENGLPG第九版学习 -视口变换、裁减、剪切与反馈
  • dpm_sysfs_add
  • 《算法精解:C语言描述》note-2 链表
  • 文章记单词 | 第64篇(六级)
  • 【Godot】使用 Shader 实现可调节的精确切角效果
  • 超详细讲解C语言转义字符\a \b \r \t \? \n等等
  • 数模13种可视化脚本-Python
  • QT设计权限管理系统
  • BUUCTF Pwn wustctf2020_closed WP
  • 【JAVA】String类深度解析:不可变性与常量池(10)
  • 五年级数学知识边界总结思考-上册
  • 含铜废水的资源化利用