实用类型验证
类型验证策略
graph TD
A[类型验证] --> B[运行时检查]
A --> C[静态类型检查]
A --> D[自定义验证]
运行时类型检查方法
使用 isinstance() 函数
def validate_input(value, expected_type):
if not isinstance(value, expected_type):
raise TypeError(f"预期为 {expected_type},得到的是 {type(value)}")
def process_data(data: int) -> int:
validate_input(data, int)
return data * 2
类型验证装饰器
def type_check(func):
def wrapper(*args, **kwargs):
## 提取类型提示
annotations = func.__annotations__
## 检查参数类型
for name, value in list(kwargs.items()) + list(zip(func.__code__.co_varnames, args)):
if name in annotations:
expected_type = annotations[name]
if not isinstance(value, expected_type):
raise TypeError(f"{name} 必须是 {expected_type}")
return func(*args, **kwargs)
return wrapper
@type_check
def create_user(name: str, age: int):
return f"用户 {name} 年龄为 {age} 岁"
验证技术比较
技术 |
优点 |
缺点 |
isinstance() |
简单,内置 |
手动实现 |
装饰器 |
可复用 |
性能开销 |
类型保护 |
精确 |
需要仔细实现 |
高级验证模式
复杂类型验证
from typing import List, Union
def validate_complex_type(value: Union[List[int], str]):
if isinstance(value, list):
## 验证整数列表
if not all(isinstance(item, int) for item in value):
raise TypeError("列表必须只包含整数")
elif isinstance(value, str):
## 验证字符串长度
if len(value) > 50:
raise ValueError("字符串太长")
else:
raise TypeError("无效输入类型")
## 使用示例
validate_complex_type([1, 2, 3]) ## 有效
validate_complex_type("短字符串") ## 有效
## validate_complex_type([1, 'a', 3]) ## 引发 TypeError
第三方类型验证库
使用 Pydantic 进行高级验证
from pydantic import BaseModel, validator
class User(BaseModel):
name: str
age: int
@validator('age')
def validate_age(cls, v):
if v < 0:
raise ValueError('年龄必须为正数')
return v
## 创建并验证用户
try:
user = User(name="John", age=30)
print(user)
except ValueError as e:
print(f"验证错误: {e}")
LabEx 最佳实践
在 LabEx,我们建议:
- 将类型提示与运行时验证相结合
- 使用像 mypy 这样的类型检查工具
- 针对复杂场景实现自定义验证
性能考量
graph LR
A[类型验证] --> B{性能影响}
B --> |轻量级| C[最小开销]
B --> |重量级| D[显著减速]
C --> E[推荐方法]
关键要点
- 存在多种类型验证方法
- 运行时检查补充静态类型提示
- 根据具体需求选择验证方法
- 在类型安全和性能之间取得平衡至关重要