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

Python自定义str子类实现开关类时报decoding str is not supported错误咨询

报错根本原因

str是Python内置的不可变类型,实例的初始化逻辑在__new__方法而非__init__方法中执行。你没有重写switch类的__new__方法,实例化时传入的3个参数会直接交给父类str的默认构造方法处理。
而str的构造方法仅支持两种调用形式:

  • 单参数形式:str(任意对象),将输入对象转为字符串
  • 三参数形式:str(字节序列, encoding=编码, errors=错误处理策略),将字节序列解码为字符串
    你传入了3个字符串参数,触发了第二种解码逻辑,但第一个参数不是字节序列而是字符串,因此抛出TypeError: decoding str is not supported的错误,和你猜想的可变参数拆分无关。
你代码的其他逻辑问题
  • 不可变类型的实例创建完成后,值无法修改,你在__init__和swap方法中写的self = xxx只是对局部变量self赋值,不会修改实例本身的实际值,完全没有效果。
  • 你定义的类属性pos没有实际作用,后续你在__init__中给实例绑定了同名属性self.pos,不会用到类属性的值。
可行的实现方案

你要的开关档位可变的需求本身不适合继承不可变的str,改用组合模式即可,通过实现魔法方法让它的表现和字符串一致:

class Switch:
    def __init__(self, *positions):
        if not positions:
            raise ValueError("必须至少传入1个档位")
        self.positions = [str(p) for p in positions]
        self._current_idx = 0

    def swap(self):
        self._current_idx = (self._current_idx + 1) % len(self.positions)

    def __str__(self):
        return self.positions[self._current_idx]

    # 代理所有字符串方法,让实例可以像普通字符串一样调用方法
    def __getattr__(self, method_name):
        return getattr(str(self), method_name)

测试效果:

mood = Switch("upbeat","depressed","horny")
print(mood) # 输出 upbeat
mood.swap()
print(mood) # 输出 depressed
mood.swap()
print(mood) # 输出 horny
mood.swap()
print(mood) # 输出 upbeat
print(mood.upper()) # 输出 UPBEAT,支持字符串方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 08:54:02