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

如何在Python中用非兼容类型简洁构造NewType?

如何让NewType自动完成类型转换?

我用typing.NewType定义了多个标识符类型,用来避免不同类型的ID被意外混用:

from typing import NewType
UserId = NewType('UserId', int)

但在处理HTTP路由的查询参数时,每次都要手动把字符串转成int再包装成UserId,写法很繁琐:

@app.get('/some_route')
def some_route():
    user = UserId(int(request.args['user_id']))

有没有简洁的方式,让UserId初始化时自动调用int的构造函数?希望能直接写成下面这样,而且不用为每个类型单独创建类:

@app.get('/some_route')
def some_route():
    user = UserId(request.args['user_id'])

解决方案:封装一个自动转换的NewType工厂函数

你可以自己写一个简单的工厂函数,替代原生的NewType,让它自动用原始类型的构造函数处理输入值:

from typing import NewType, TypeVar

T = TypeVar('T')

def AutoNewType(name: str, base_type: type[T]) -> type[T]:
    def auto_convert_wrapper(value):
        # 先调用基础类型的构造函数转换值,再用NewType包装
        return NewType(name, base_type)(base_type(value))
    return auto_convert_wrapper

使用方式

用这个AutoNewType代替原生NewType来定义你的标识符类型:

# 定义时和原生NewType写法几乎一致
UserId = AutoNewType('UserId', int)
PostId = AutoNewType('PostId', int)

现在就可以直接传入字符串,自动完成转换:

@app.get('/some_route')
def some_route():
    # 自动将字符串转成int后包装为UserId
    user = UserId(request.args['user_id'])

验证效果

测试一下转换逻辑:

user_id = UserId("123")
print(type(user_id))  # 输出 <class 'UserId'>
print(user_id == 123)  # 输出 True

# 传入int类型也能正常工作
another_user_id = UserId(456)
print(another_user_id == 456)  # 输出 True

这种方式既保留了NewType的类型安全特性,又省去了手动转换的冗余代码,而且不需要为每个类型创建单独的类,完全符合你的需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 23:35:21