Python类型提示进阶:超越基础注解的实践技巧
Python的类型提示(Type Hints)早已不是简单的"类型标注"。随着Python 3.10+的发布,类型系统变得更加强大和实用。让我们看看如何超越基础用法,编写更安全、更清晰的代码。
联合类型与类型守卫
# 传统方式
def process(data: Union[str, list]) -> int:
if isinstance(data, str):
return len(data)
else:
return sum(data)
# 现代方式:使用TypeGuard
from typing import TypeGuard
def is_str_list(val: list) -> TypeGuard[list[str]]:
return all(isinstance(item, str) for item in val)
def handle_items(items: list[str | int]) -> list[str]:
if is_str_list(items):
return items # 这里items自动识别为list[str]
return []
数据类与类型结合
from dataclasses import dataclass
from typing import ClassVar
@dataclass
class User:
name: str
age: int
active: bool = True # 默认值
_id_counter: ClassVar[int] = 0 # 类变量
def __post_init__(self):
self._validate()
@classmethod
def create(cls, name: str) -> "User":
cls._id_counter += 1
return cls(name=name, age=0)
泛型的高级应用
from typing import Generic, TypeVar, Iterable
from collections.abc import Iterator
T = TypeVar('T')
U = TypeVar('U')
class BatchProcessor(Generic[T, U]):
def __init__(self, converter: Callable[[T], U]):
self.converter = converter
def process_batch(self, items: Iterable[T]) -> Iterator[U]:
return map(self.converter, items)
# 使用
processor = BatchProcessor[str, int](len)
result = list(processor.process_batch(["a", "bb", "ccc"]))
# result: [1, 2, 3]
实践建议
- 渐进式采用:从关键函数开始,逐步覆盖整个项目
- 配合静态检查工具:使用mypy或pyright捕获类型错误
- 类型别名提高可读性:
UserId = NewType('UserId', int) - 合理使用
Any:明确标记需要动态性的地方,而非逃避类型检查
类型提示不仅是文档,更是通过静态检查预防bug的利器。善用这些特性能让你的Python代码在保持灵活性的同时,获得更强的可靠性和可维护性。