typing 模块提供了许多高级特性,这些特性可以帮助开发者编写更健壮、更易维护的代码。 以下是一些高级用法的详细解析,结合了最新的 typing 模块功能和 typing-extensions 包的内容。
基础类型
Any:任意类型
表示变量可以是任何类型,完全禁用类型检查(慎用,优先用更具体的类型)。
from typing import Any
def print_anything(data: Any) -> None:
print(data) # 可以是 int、str、dict 等任意类型
print_anything(42) # 合法
print_anything("hello")# 合法
Union:联合类型
表示变量可以是多个类型中的一种(Python 3.10+ 可用 | 替代)。
from typing import Union
def parse_input(data: Union[str, int]) -> str:
return str(data) # 接受 str 或 int,返回 str
# Python 3.10+ 等价写法
def parse_input_v2(data: str | int) -> str:
return str(data)
print(parse_input(100)) # 输出 "100"
print(parse_input("abc")) # 输出 "abc"
Optional:可选类型
等价于 Union[T, None],表示变量可能是某个类型或 None。
from typing import Optional
def find_user(user_id: int) -> Optional[str]:
if user_id == 1:
return "Alice" # 返回 str
else:
return None # 返回 None
user = find_user(1)
if user is not None:
print(user.upper()) # 类型检查器知道此处 user 是 str
容器类型
List/list:列表
指定列表元素的类型。
from typing import List
def sum_numbers(nums: List[int]) -> int:
return sum(nums) # 确保列表元素全是 int
# Python 3.9+ 内置泛型写法
def sum_numbers_v2(nums: list[int]) -> int:
return sum(nums)
sum_numbers([1, 2, 3]) # 合法
sum_numbers(["a", "b"]) # 类型检查报错(元素不是 int)
Dict / dict:字典
指定键和值的类型。
from typing import Dict
def get_population() -> Dict[str, int]:
return {"China": 1410, "India": 1380} # 键为 str,值为 int
# Python 3.9+ 写法
def get_population_v2() -> dict[str, int]:
return {"China": 1410, "India": 1380}
population = get_population()
print(population["China"] + 10) # 类型检查器知道值是 int
Tuple / tuple:元组
- 固定长度和类型:精确指定每个位置的类型。
- 不定长元组:用 ... 表示剩余元素类型相同。
from typing import Tuple
def get_coordinates() -> Tuple[float, float]:
return (40.7128, -74.0060) # 两个 float 元素
# 不定长元组(Python 3.9+)
def process_data(data: tuple[int, ...]) -> int:
return sum(data) # 所有元素必须是 int
process_data((1, 2, 3)) # 合法
process_data((1, "a")) # 类型检查报错(第二个元素不是 int)
Set / set:集合
指定集合元素的类型。
from typing import Set
def unique_values(items: Set[str]) -> int:
return len(items) # 元素必须是 str
# Python 3.9+ 写法
def unique_values_v2(items: set[str]) -> int:
return len(items)
unique_values({"apple", "banana"}) # 合法
unique_values({1, 2}) # 类型检查报错
泛型与类型变量
TypeVar:定义泛型类型变量
创建可复用的泛型函数或类。
from typing import TypeVar, List
T = TypeVar('T') # 可以是任何类型
def first_element(items: List[T]) -> T:
return items # 返回类型与列表元素类型相同
print(first_element([1, 2, 3])) # 返回 int 类型(1)
print(first_element(["a", "b"])) # 返回 str 类型("a")
Generic:泛型类
创建可参数化的类。
from typing import Generic, TypeVar, List
T = TypeVar('T')
class Stack(Generic[T]):
def __init__(self) -> None:
self.items: List[T] = []
def push(self, item: T) -> None:
self.items.append(item)
def pop(self) -> T:
return self.items.pop()
# 实例化时指定具体类型
stack_int = Stack:ml-search[int]
stack_int.push(42)
stack_int.push("hello") # 类型检查报错(非 int 类型)
stack_str = Stack:ml-search[str]
stack_str.push("world") # 合法
函数与回调
Callable:函数签名
定义回调函数的参数和返回值类型。
from typing import Callable
def apply_operation(
x: int,
y: int,
op: Callable[[int, int], int] # 接受两个 int 参数,返回 int
) -> int:
return op(x, y)
# 合法操作
print(apply_operation(3, 4, lambda a, b: a * b)) # 输出 12
# 非法操作(类型检查报错)
apply_operation(3, 4, lambda a: a) # 回调函数参数数量不匹配
迭代器和生成器
- Generator[YieldType, SendType, ReturnType]:定义生成器的产出值、发送值和返回值。
- Iterable[T]:可迭代对象。
- Iterable[T]:迭代器。
from typing import Generator, Iterable, Iterator
def count_up_to(n: int) -> Generator[int, None, None]:
"""生成器产出 int,不接收 send 值,无返回值"""
i = 1
while i <= n:
yield i
i += 1
def print_all(items: Iterable[str]) -> None:
for item in items:
print(item)
def square_numbers(nums: list[int]) -> Iterator[int]:
return (num ** 2 for num in nums) # 返回生成器表达式(迭代器)
# 使用示例
for num in count_up_to(5):
print(num) # 输出 1, 2, 3, 4, 5
高级类型
Literal
字面量类型(Python 3.8+),限制变量只能取特定的字面量值。
from typing import Literal
def set_status(status: Literal["active", "inactive"]) -> None:
print(f"Status set to {status}")
set_status("active") # 合法
set_status("pending") # 类型检查报错(不在允许的字面量中)
TypedDict
类型化字典(Python 3.8+),定义字典的键和值类型,增强代码可读性和安全性。
from typing import TypedDict
class User(TypedDict):
name: str
age: int
is_active: bool
def create_user() -> User:
return {
"name": "Bob",
"age": 30,
"is_active": True,
"email": "bob@example.com" # 类型检查报错(不在定义中)
}
Protocol
结构子类型(Python 3.8+),定义接口协议(无需继承,只要实现特定方法)。
from typing import Protocol
class Printable(Protocol):
def print(self) -> None:
... # 只需实现 print 方法即可符合协议
class Document:
def print(self) -> None:
print("Printing document...")
class Image:
def print(self) -> None:
print("Printing image...")
def log_print(obj: Printable) -> None:
obj.print()
log_print(Document()) # 合法
log_print(Image()) # 合法
其他实用类型
NewType:创建新类型
定义具有语义的新类型(运行时无开销,仅用于类型检查)。
from typing import NewType
UserId = NewType("UserId", int) # UserId 是 int 的派生类型
def get_user(id: UserId) -> str:
return f"User {id}"
user_id = UserId(1001) # 创建 UserId 类型变量
print(get_user(user_id)) # 合法
# 直接传递 int 会报错
print(get_user(1001)) # 类型检查报错(需要 UserId 类型)
Type:类类型
表示类本身(而非实例),常用于工厂模式。
from typing import Type
class Animal:
def speak(self) -> str:
return "..."
class Dog(Animal):
def speak(self) -> str:
return "Woof!"
def create_animal(cls: Type[Animal]) -> Animal:
return cls() # 创建类的实例
print(create_animal(Dog).speak()) # 输出 "Woof!"
Final
常量(Python 3.8+),标记变量不可被重新赋值。
from typing import Final
MAX_SIZE: Final[int] = 100
MAX_SIZE = 200 # 类型检查报错(不可修改)
Annotated
Annotated 允许你在类型提示中添加元数据,这可以用于验证或文档目的。
from typing import Annotated
def process_value(value: Annotated[int, "Must be a positive integer"]) -> int:
if value < 0:
raise ValueError("Value must be positive!")
return value
print(process_value(10)) # 正确
# print(process_value(-1)) # 会抛出 ValueError
Self
Self 类型简化了返回当前实例的方法的类型注解。
from typing import Self
class Builder:
def __init__(self):
self.data = []
def add(self, value: int) -> Self:
self.data.append(value)
return self
builder = Builder().add(10).add(20)
print(builder.data) # 输出: [10, 20]
Unpack 和变长泛型
Unpack 用于变长泛型,允许你解包类型序列。
from typing import TypeVarTuple, Unpack
Shape = TypeVarTuple("Shape")
def print_shapes(*shapes: Unpack[Shape]) -> None:
for shape in shapes:
print(shape)
print_shapes(1, 2, 3) # 正确
协变与逆变
协变(Covariant)
允许子类替代父类(常见于只读容器)。
from typing import TypeVar, Generic
class Animal: pass
class Dog(Animal): pass
T_co = TypeVar("T_co", covariant=True)
class ImmutableList(Generic[T_co]):
def __init__(self, items: list[T_co]) -> None:
self.items = items
def get(self, index: int) -> T_co:
return self.items[index]
# 协变允许将 ImmutableList[Dog] 赋值给 ImmutableList[Animal]
animals: ImmutableList[Animal] = ImmutableList([Dog(), Dog()])
逆变(Contravariant)
允许父类替代子类(常见于函数参数)。
from typing import TypeVar, Generic, Callable
class Animal: pass
class Dog(Animal): pass
T_contra = TypeVar("T_contra", contravariant=True)
class EventHandler(Generic[T_contra]):
def handle(self, data: T_contra) -> None:
print(f"Handling {type(data).__name__}")
# 逆变允许将 EventHandler[Animal] 赋值给 EventHandler[Dog]
def process_event(handler: EventHandler[Dog]) -> None:
handler.handle(Dog())
animal_handler = EventHandler:ml-search[Animal]
process_event(animal_handler) # 合法
← Previous postPython中的List列表常见和高级用法
Next post →Python中的Closure闭包