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

如何在继承typing.Tuple时初始化基础tuple对象?

解决继承Tuple[int, int]时的初始化问题

这个问题的核心在于:typing.Tuple本质上是设计用来做类型提示的工具,虽然PEP 484提到它可以用作基类,但它的内部实现并没有像内置tuple那样处理子类的实例化逻辑,导致参数没有正确转发到底层的tuple对象。

方案1:重写__new__方法(兼容旧Python版本)

因为tuple是不可变类型,实例创建依赖__new__方法而不是__init__。我们需要手动把参数转发给父类的__new__,确保底层tuple被正确初始化:

from typing import Tuple

class MyTuple(Tuple[int, int]):
    def __new__(cls, *args, **kwargs):
        # 把所有参数转发给父类的__new__方法
        return super().__new__(cls, *args, **kwargs)
    
    def hello(self):
        print("hello: " + str(len(self)))

# 两种调用方式都能正常工作
MyTuple(1, 2).hello()       # 输出: hello: 2
MyTuple([1, 2]).hello()     # 输出: hello: 2

方案2:使用PEP 585内置泛型(推荐Python 3.9+)

从Python 3.9开始,内置的tuple、list等类型已经支持泛型注解,不需要再用typing.Tuple来做基类。这种方式更直观,也能避免旧typing模块的坑:

from typing import Generic, TypeVar

# 定义类型变量,用于约束元组的元素类型
T = TypeVar('T')
U = TypeVar('U')

class MyTuple(tuple[T, U], Generic[T, U]):
    def hello(self):
        print("hello: " + str(len(self)))

# 同样支持两种调用方式
MyTuple(1, 2).hello()       # 输出: hello: 2
MyTuple([1, 2]).hello()     # 输出: hello: 2

为什么原来的代码会输出hello: 0?

当你直接继承typing.Tuple[int, int]且不重写__new__时,子类的构造逻辑并没有正确把传入的可迭代对象[1,2]传递给底层的tuple构造函数,导致创建了一个空的tuple实例,所以len(self)返回0。而继承内置tuple时,Python会自动处理参数转发,所以能正确初始化。

内容的提问来源于stack exchange,提问作者Martin C. Martin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:24:38