Python中的Super方法实现问题及解决方案

1、问题背景

在Python中,super方法用于在子类中调用父类的方法。Guido van Rossum曾给出了一个纯Python实现的super方法,以便更好地理解其工作原理。然而,在这个实现中,存在一个问题:当传入的对象不是要调用的父类的实例时,该实现会出错。

2、解决方案

为了解决这个问题,需要对Guido的实现进行修改。具体来说,需要在__getattr__()方法中添加一个检查,以确保传入的对象是给定类型的实例。如果传入的对象不是给定类型的实例,那么就引发一个错误。

以下是修改后的__getattr__()方法:

python 复制代码
    def __getattr__(self, attr):
        if isinstance(self.__obj__, self.__type__):
            starttype = self.__obj__.__class__
        else:
            # 检查传入的对象是否是给定类型的实例
            if not isinstance(self.__obj__, self.__type__):
                raise TypeError("obj must be an instance or subtype of type")
            starttype = self.__obj__

        mro = iter(starttype.__mro__)
        for cls in mro:
            if cls is self.__type__:
                break
        # Note: mro is an iterator, so the second loop
        # picks up where the first one left off!
        for cls in mro:
            if attr in cls.__dict__:
                x = cls.__dict__[attr]
                if hasattr(x, "__get__"):
                    x = x.__get__(self.__obj__)
                return x
        raise AttributeError, attr

通过这个修改,就可以确保传入的对象是给定类型的实例,从而避免了错误的发生。

以下是修改后的代码示例:

python 复制代码
class Super(object):
    def __init__(self, type, obj=None):
        self.__type__ = type
        self.__obj__ = obj

    def __get__(self, obj, type=None):
        if self.__obj__ is None and obj is not None:
            return Super(self.__type__, obj)
        else:
            return self

    def __getattr__(self, attr):
        # 检查传入的对象是否是给定类型的实例
        if not isinstance(self.__obj__, self.__type__):
            raise TypeError("obj must be an instance or subtype of type")

        if isinstance(self.__obj__, self.__type__):
            starttype = self.__obj__.__class__
        else:
            starttype = self.__obj__

        mro = iter(starttype.__mro__)
        for cls in mro:
            if cls is self.__type__:
                break
        # Note: mro is an iterator, so the second loop
        # picks up where the first one left off!
        for cls in mro:
            if attr in cls.__dict__:
                x = cls.__dict__[attr]
                if hasattr(x, "__get__"):
                    x = x.__get__(self.__obj__)
                return x
        raise AttributeError, attr

class A(object):
    def m(self):
        '''  m in A'''
        return "A"

class B(A):
    def m(self):
        '''  m in B'''
        return "B" + Super(B, self).m()

class C(A):
    def m(self):
        ''' m in C '''
        return "C" + Super(C, self).m()

class D(C):
    def m(self):
        ''' m in D'''
        return "D" + Super(B, self).m()

print(D().m()) # "DCBA"

现在,该代码就可以正确地运行,并且不会引发错误。

相关推荐
在世修行3 分钟前
智学文枢:页面切换与跨页数据预填
python·桌面应用·signal·1024程序员节·pyside·跨页跳转·状态预填
2601_9628857227 分钟前
如何用 Python 把 K 线重采样成任意周期?
开发语言·python
打工仔折腾 AI31 分钟前
在 Ubuntu ARM64 部署 Q1 V3.0 MuJoCo 模型:加载、单步推理与执行器响应解析
linux·运维·人工智能·python·深度学习·ubuntu·性能优化
信誓旦旦的程序猿1 小时前
【Python量化实战宝典 #21】北向资金跟随手册:聪明钱择时信号(Python 可跑)
python·1024程序员节·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
严谨的麻辣烫2 小时前
静态 ISP 代理请求超时怎么排查?Python 与 curl 实战
python·http·requests·1024程序员节·网络排障
KeepRobots3 小时前
11-01 温哥华不回拨:用 60 行 Python 查你的工单系统会不会差一小时(KeepRobots 工程笔记)
python
xiao77mwq3 小时前
你以为 OCR 慢?实测 81.3 s 里全是故障代价:如何把「定格态」消掉,让耗时从 6.5 s 到 13 倍差距显出原形
python
深圳市益普科技有限公司3 小时前
半导体良率管理YMS:良率与设备参数的相关性,先拉哪几组数据
人工智能·python·算法
“AI国潮设计-小江”4 小时前
【AIGC实战】Python+SDXL打造“潮汕英歌舞IP”万能立牌插件,批量生成“发财元宝蛋糕”视觉营销方案(附源码)
开发语言·人工智能·python·prompt·aigc
砚底藏山河5 小时前
python量化实操:冷热分层存储
java·开发语言·python·金融