Python 中的 NewType
发布: (2026年1月3日 GMT+8 15:47)
4 min read
原文: Dev.to
Source: Dev.to
概览
NewType 允许你创建一个 独立的类型,在静态类型检查器(例如 mypy)中被视为不同的类型,而在运行时只是其基类型的别名。它自 Python 3.5.2 起可用。
关键特性
- 新类型是 唯一的,与其基类型不同。
- 只能从 非 Union(即非
typing.Union)类型创建。 - 生成的类型表现得像基类型的 子类型。
- 不能使用普通类对其进行 子类化。
语法
from typing import NewType, reveal_type
# name: 必需的字符串,必须与变量名匹配
# tp: 必需的非 Union 类型
NT1 = NewType('NT1', int)
NT2 = NewType('NT2', list[int | float])
重要说明
- 第一个参数(
name)是一个字符串,应该与变量名完全相同。 - 第二个参数(
tp)必须是具体的、非 Union 类型。 - 使用 Union 类型(例如
int | float)会导致错误。
基本用法
from typing import NewType, reveal_type
NT1 = NewType('NT1', int)
NT2 = NewType('NT2', list[int | float])
reveal_type(NT1(100)) # -> int (type checker shows test.NT1)
reveal_type(NT2([0, 1, 2])) # -> list (type checker shows test.NT2)
# 以下为错误(类型检查器 / 运行时):
# NT3 = NewType('NT3', int | float) # ❌ 不允许使用 Union
# NT50 = NewType('NT100', int) # ❌ 名称不匹配
NewType 之间的交互
from typing import NewType
NT1 = NewType('NT1', int)
NT2 = NewType('NT2', NT1)
# 赋值
a1: NT1 = 100 # ❌ 错误
a2: NT1 = NT1(100) # ✅ 没有错误
a3: NT1 = NT2(100) # ❌ 错误
a4: NT1 = NT2(NT1(100)) # ✅ 没有错误
a5: NT1 = NT1(NT2(100)) # ❌ 错误
b1: NT2 = 100 # ❌ 错误
b2: NT2 = NT1(100) # ❌ 错误
b3: NT2 = NT2(100) # ❌ 错误
b4: NT2 = NT2(NT1(100)) # ✅ 没有错误
b5: NT2 = NT1(NT2(100)) # ❌ 错误
c1: int = 100 # ✅ 没有错误
c2: int = NT1(100) # ✅ 没有错误
c3: int = NT2(100) # ❌ 错误
c4: int = NT2(NT1(100)) # ✅ 没有错误
c5: int = NT1(NT2(100)) # ❌ 错误
print(a4 + b4 + c4) # ✅ 没有错误
与类型别名和泛型一起使用 NewType
from typing import NewType
type TA1 = int
type TA2[T] = T
NT1 = NewType('NT1', TA1) # ✅ 没有错误
NT2 = NewType('NT2', TA2[int]) # ✅ 没有错误
无效的泛型用法
from typing import NewType
NT = NewType('NT', list)
v: NT[int] # ❌ 错误 – NewType 不支持泛型参数
对 NewType 进行子类化
from typing import NewType
NT = NewType('NT', int)
class Cls(NT): # ❌ 错误 – NewType 不能被子类化
pass
参考资料
- Python 文档: typing.NewType
- 相关备忘录: Memo for type‑hints‑related posts in Python
本文基于之前关于类型提示的文章:
- Type hints in Python (part 1) (解释基本类型提示)