You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中继承内置类时,如何返回自定义类类型而非内置类型?

解决继承str后内置方法返回str类型的问题

问题核心是:Python内置str类的方法(如upper()、lower()、strip()等)返回的是原生str实例,而非自定义子类StringMethods的实例,导致调用后类型丢失。以下是两种可行的解决方案:

方案一:逐个重写返回str的内置方法

直接重写需要用到的str方法,在调用父类方法后将结果包装为StringMethods实例。这种方式适合需要精准控制个别方法行为的场景。

示例重写几个常用方法:

def upper(self) -> "StringMethods":
    return StringMethods(super().upper())

def lower(self) -> "StringMethods":
    return StringMethods(super().lower())

def strip(self, chars=None) -> "StringMethods":
    return StringMethods(super().strip(chars))

方案二:利用__getattr__统一处理

通过__getattr__拦截所有未在子类中定义的方法调用,自动将str方法的返回值转换为StringMethods实例。这种方式无需逐个重写方法,更简洁通用。

同时需要修正你自定义方法中的返回值——原代码中removechar、removechars、__sub__、__add__等方法返回的是原生str,需要包装为StringMethods实例。

修改后的完整代码

from typing import Iterable

class StringMethods(str):
    """
    StringMethods class:

    A class inheriting from the built in python 'str' class,
    but with extended methods for string analysis, password checking etc.
    """        
    def contains(self, char: str) -> bool:
        """ True if self contains specified char """
        return char in self

    def containsany(self, chars: Iterable) -> bool:
        """ True if self contains any specifed chars """
        for char in chars:
            if str(char) in self:
                return True
        return False

    def hasdigit(self) -> bool: 
        return self.containsany("0123456789")
    def haslower(self) -> bool: 
        return self.containsany("abcdefghijklmnopqrstuvwxyz")
    def hasupper(self) -> bool: 
        return self.containsany("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
    def haswhitespace(self) -> bool: 
        return self.contains(" ")
    
    def removechar(self, char: str) -> "StringMethods":
        """ Remove all instances of specified char from self """
        return StringMethods("".join([i for i in self if i != str(char)]))
        
    def removechars(self, chars: Iterable) -> "StringMethods":
        """ Remove all specified chars from self """
        chars = [str(char) for char in chars]
        return StringMethods("".join([i for i in self if str(i) not in chars]))
    
    def __sub__(self, subtrahend) -> "StringMethods":
        return StringMethods(self[:-subtrahend])
    
    def __add__(self, addend) -> "StringMethods":
        return StringMethods(f"{self}{self[-1]}")
    
    def __getattr__(self, name):
        # 获取父类str的方法或属性
        attr = getattr(super(), name)
        if callable(attr):
            # 包装方法,将返回的str转为StringMethods实例
            def wrapper(*args, **kwargs):
                result = attr(*args, **kwargs)
                return StringMethods(result) if isinstance(result, str) else result
            return wrapper
        return attr

# 测试
y = StringMethods("hello")
y_upper = y.upper()
print(type(y_upper))  # 输出: <class '__main__.StringMethods'>
print(y_upper.haslower())  # 输出: False
print(y_upper.removechar("L"))  # 输出: HELO

注意事项

  • __getattr__只会拦截子类中未定义的方法,因此你自定义的contains、hasdigit等方法不受影响。
  • 对于少数特殊的魔法方法(如__len__、__getitem__),__getattr__无法拦截,因为Python会优先在类的属性字典中查找魔法方法。如果需要处理这些方法,仍需手动重写。

内容的提问来源于stack exchange,提问作者darragh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 20:35:20