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

Python如何在返回类型提示中定义并返回匿名NamedTuple

Python实现类似TypeScript匿名返回类型的正确方式

问题说明

从TypeScript转刚接触Python,想实现TS里那种不用单独声明类、直接在函数返回类型里定义匿名对象结构的效果——既能获得IDE自动补全和错误提示,又不用额外写类声明。试了用NamedTuple但报错,PyCharm提示:期望类型'MyTuple',实际得到'dict[str, str | int]'

错误代码示例:

def fn(self) -> NamedTuple('MyTuple', fields = [('params', str), ('cursor_end', int)]):
    return {
        'params': 'hello',
        'cursor_end': 4,
    }

正确实现方案

方案1:用TypedDict(最贴合TS匿名对象逻辑,推荐)

Python的TypedDict就是专门用来定义字典的键值类型结构的,完全符合你的需求——不用单独声明类,直接在返回类型里定义结构,返回普通字典就能通过类型检查,IDE也能正常补全:

Python 3.10及以下写法

from typing import TypedDict

def fn(self) -> TypedDict('MyDict', {'params': str, 'cursor_end': int}):
    return {
        'params': 'hello',
        'cursor_end': 4,
    }

Python 3.12+简化写法

from typing import TypedDict

def fn(self) -> TypedDict('MyDict', params=str, cursor_end=int):
    return {
        'params': 'hello',
        'cursor_end': 4,
    }

方案2:NamedTuple的正确用法

如果你非要用NamedTuple,不能返回字典,得返回它生成的类的实例。不过这种写法IDE识别可能不如TypedDict顺畅:

from typing import NamedTuple

def fn(self) -> NamedTuple('MyTuple', [('params', str), ('cursor_end', int)]):
    # 用生成的类创建实例返回
    return type(self.fn.__annotations__['return'])(params='hello', cursor_end=4)

或者更直白一点,提前在函数内部创建类:

from typing import NamedTuple

def fn(self):
    MyTuple = NamedTuple('MyTuple', [('params', str), ('cursor_end', int)])
    return MyTuple(params='hello', cursor_end=4)

方案3:临时dataclass(Python 3.7+)

用dataclass创建临时类,同样不用单独声明,但写法稍显繁琐:

from dataclasses import dataclass

def fn(self) -> dataclass(frozen=True)(type('MyData', (), {'params': str, 'cursor_end': int})):
    return type('MyData', (), {'params': 'hello', 'cursor_end': 4})()

错误原因

你之前的代码之所以报错,是因为NamedTuple('MyTuple', ...)生成的是一个新的元组子类,而你返回的是普通字典,两者类型完全不匹配。TypedDict则是专门用来标注字典类型的,和TS里的匿名对象逻辑一致,所以返回字典完全符合要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 14:37:37