如何在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
相关产品推荐
相关产品推荐

