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

泛型类中使用PEP 673 Self[DataOut]报错,该用法是否支持?

问题解答

当前PEP 673定义的Self类型不支持Self[DataOut]这种带类型参数的写法,这也是你在Pylance/Pyright中报错的原因。

为什么不行?

Self的设计初衷是指代当前实例的具体类型——包括它已经绑定的泛型参数。比如你有一个Msg[int]的实例,Self就等价于Msg[int],它是一个具体的类型,而非可以重新指定泛型参数的类模板。所以给Self添加类型参数本身就不符合它的语义,类型检查器自然会报错。

PEP 673文档中提到的“Self也可用于泛型类方法”,指的是在方法中返回与当前实例同泛型参数的实例场景,比如:

def clone(self) -> Self:
    return Msg(source=self.source, data=self.data)

这种场景下Self可以正确指代当前实例的泛型类型,而不是用来生成一个新泛型参数的实例。

替代方案

如果你想避免使用字符串引用,有两种可行的方式:

1. 启用延迟注解(Python 3.10+)

导入from __future__ import annotations后,类型注解会延迟解析,直接写Msg[DataOut]即可,不需要加引号:

from __future__ import annotations
from dataclasses import dataclass
from typing import Generic, TypeVar

DataIn = TypeVar('DataIn')
DataOut = TypeVar('DataOut')

@dataclass
class Msg(Generic[DataIn]):
    source: str
    data: DataIn

    def next(self, data: DataOut) -> Msg[DataOut]:
        """创建一个相同source但不同data的新消息"""
        return Msg(source=self.source, data=data)

2. 使用绑定的TypeVar(兼容更早版本)

定义一个绑定到Msg的TypeVar,用来表示泛型的Msg类型:

from dataclasses import dataclass
from typing import Generic, TypeVar

DataIn = TypeVar('DataIn')
DataOut = TypeVar('DataOut')
MsgType = TypeVar('MsgType', bound='Msg')

@dataclass
class Msg(Generic[DataIn]):
    source: str
    data: DataIn

    def next(self, data: DataOut) -> Msg[DataOut]:
        return Msg(source=self.source, data=data)

总结

返回不同泛型参数的同类实例时,Self类型无法满足需求,推荐直接使用类名加类型参数的写法(启用延迟注解后无需字符串)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 18:52:37