Python类型系统进阶:5个Type Hint高级应用场景
1. 泛型编程实战
使用TypeVar和Generic实现泛型容器:
from typing import TypeVar, Generic, 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()
# 使用示例
int_stack = Stack[int]()
int_stack.push(1)
# int_stack.push("string") # mypy会报错
str_stack = Stack[str]()
str_stack.push("hello")
2. 精确类型约束
使用Literal和NewType创建精确类型:
from typing import Literal, NewType
HttpMethod = Literal['GET', 'POST', 'PUT', 'DELETE']
UserId = NewType('UserId', int)
def handle_request(method: HttpMethod, user_id: UserId) -> None:
print(f"处理 {method} 请求,用户ID: {user_id}")
# 正确用法
handle_request('GET', UserId(123))
# 错误用法
# handle_request('PATCH', 123) # mypy会报错
3. 复杂类型组合
使用Union和Optional处理多种类型:
from typing import Union, Optional, Dict, List
JsonValue = Union[str, int, float, bool, None,
List['JsonValue'], Dict[str, 'JsonValue']]
def parse_json(data: JsonValue) -> Optional[str]:
if isinstance(data, dict):
return data.get("message")
return None
# 类型检查会验证嵌套结构
data: JsonValue = {
"message": "success",
"items": [1, 2, 3]
}
result = parse_json(data)
4. 回调函数类型标注
精确标注回调函数类型:
from typing import Callable, TypeVar
R = TypeVar('R')
def retry(
func: Callable[..., R],
max_attempts: int = 3
) -> Callable[..., R]:
def wrapper(*args, **kwargs) -> R:
for attempt in range(max_attempts):
try:
return func(*args, **kwargs)
except Exception:
if attempt == max_attempts - 1:
raise
raise RuntimeError("不应执行到此处")
return wrapper
@retry
def fetch_data(url: str) -> dict:
import requests
response = requests.get(url)
return response.json()
类型特性 | Python版本 | 主要用途 |
---|---|---|
基本类型提示 | 3.5+ | 变量、函数参数和返回值 |
泛型支持 | 3.9+ | 容器类类型标注 |
精确字面量 | 3.8+ | 枚举值约束 |
5. 运行时类型检查
使用pydantic实现运行时验证:
from pydantic import BaseModel, validator
from datetime import datetime
class User(BaseModel):
id: int
name: str
signup_date: datetime
@validator('name')
def name_must_contain_space(cls, v):
if ' ' not in v:
raise ValueError('必须包含空格')
return v.title()
# 自动类型转换和验证
user = User(id=1, name='john doe', signup_date='2023-01-01')
print(user.signup_date) # 自动转为datetime对象
# 无效数据会抛出异常
# User(id='one', name='johndoe', signup_date='2023-01-01')
合理使用类型系统可以大幅提升Python代码的可靠性和可维护性,是大型项目开发的必备技能。