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"

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

相关推荐
万象观察录33 分钟前
API面临越权、爬虫、撞库等风险,有什么解决方案?
爬虫
大汉堡玩测试40 分钟前
langfuse测试实战(一): 配置一个简单的项目快速落地
python·测试工具
一位正在转型AI全栈的前端工程师1 小时前
AI 全栈学习之旅 -Week 8:从单 Agent 到多 Agent 协作:LangGraph 实战与记忆持久化
前端·python
长江后浪博客1 小时前
Python + YOLOv8 疲劳驾驶 AI 视觉检测入门:从模型训练到 ONNX 实时摄像头检测完整实战
人工智能·python·yolo·疲劳驾驶检测·onnx·yolov8
hhzz1 小时前
【OpenCV 入门到精通 01】认识 OpenCV 与计算机视觉:从零建立全局认知
人工智能·python·opencv·计算机视觉·开源
CDN3602 小时前
爬虫把价格库扒光、SQL注入打穿数据库?360CDN WAF规则引擎深度定制,把防护精度拉到逐字段级
数据库·爬虫·sql
一马平川的大草原2 小时前
如何实现SVG转Mermaid图
python·svg·格式转换·mermaid
PFFstronger2 小时前
基于 Dify 知识库 + Ollama 大模型,自动生成测试用例并导出 XMind 的完整方案
人工智能·python·测试用例·xmind
SomeBottle2 小时前
【小记】图片托管从又拍云迁移到腾讯云 EO + COS(兼容图片处理参数)
python·计算机网络·学习笔记·对象存储·cdn·折腾
cts6183 小时前
FDE架构师前端选型指南
python