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
相关产品推荐
相关产品推荐

