首页  

Python 类型提示(Type Hints)     所属分类 python 浏览量 15
Python 类型提示优点:
更好的代码可读性
早期错误检测
更好的IDE支持
提高代码质量

Python 3.10+ 提供了更简洁的语法,
建议使用新版本以获得更好的类型提示体验



1. 基础类型注解

1.1 基本类型


# 基本类型注解
def greet(name: str) -> str:
    return f"Hello, {name}"

def add(a: int, b: int) -> int:
    return a + b

def is_active(status: bool) -> bool:
    return status

def calculate_price(price: float, tax_rate: float = 0.1) -> float:
    return price * (1 + tax_rate)

# 使用示例
result: str = greet("Alice")
total: int = add(10, 20)
active: bool = is_active(True)
final_price: float = calculate_price(100.0)

1.2 变量注解

# 变量类型注解
name: str = "John"
age: int = 30
is_student: bool = False
height: float = 175.5

# 类型推断(Python 3.6+)
from typing import TypeVar

T = TypeVar('T')

def first_element(items: list[T]) -> T:
    return items[0]



2. 容器类型注解 2.1 列表、元组、字典、集合 from typing import List, Dict, Set, Tuple, Optional, Union # 列表注解 def process_numbers(numbers: List[int]) -> List[float]: return [n * 1.5 for n in numbers] # 字典注解 def process_students(students: Dict[str, int]) -> Dict[str, str]: return {name: f"Grade: {grade}" for name, grade in students.items()} # 集合注解 def unique_items(items: Set[str]) -> int: return len(items) # 元组注解(固定长度) def get_coordinates() -> Tuple[float, float]: return (40.7128, -74.0060) # 元组注解(可变长度) def process_data(data: Tuple[int, ...]) -> float: # 任意数量的int return sum(data) / len(data) # 使用示例 numbers: List[int] = [1, 2, 3, 4, 5] students: Dict[str, int] = {"Alice": 90, "Bob": 85} unique_names: Set[str] = {"Alice", "Bob", "Charlie"} coordinates: Tuple[float, float] = (40.7128, -74.0060) 2.2 更现代的语法(Python 3.9+) # Python 3.9+ 使用内置类型 def process_numbers(numbers: list[int]) -> list[float]: return [n * 1.5 for n in numbers] def process_dict(data: dict[str, int]) -> dict[str, str]: return {k: str(v) for k, v in data.items()} def get_items() -> tuple[int, str, bool]: return (1, "hello", True)
3. 复杂类型注解 3.1 Optional 和 Union from typing import Optional, Union # Optional 表示可能为 None def find_user(user_id: int) -> Optional[Dict[str, str]]: if user_id > 0: return {"id": str(user_id), "name": "John"} return None # Union 表示多种类型 def process_input(value: Union[int, str, List[int]]) -> str: if isinstance(value, int): return f"整数: {value}" elif isinstance(value, str): return f"字符串: {value}" else: return f"列表: {value}" # Python 3.10+ 使用 | 语法 def process_input_v2(value: int | str | list[int]) -> str: return str(value) # 使用示例 user: Optional[dict] = find_user(123) result: str = process_input([1, 2, 3]) 3.2 Any 和 TypeVar from typing import Any, TypeVar, Generic # Any 表示任意类型 def log_message(message: Any) -> None: print(f"[LOG]: {message}") # TypeVar 用于泛型 T = TypeVar('T') def get_first(items: list[T]) -> T: return items[0] # 多个 TypeVar K = TypeVar('K') V = TypeVar('V') def get_value(dictionary: dict[K, V], key: K) -> V: return dictionary[key] # 带约束的 TypeVar Number = TypeVar('Number', int, float) def double(value: Number) -> Number: return value * 2 # 使用示例 first_num: int = get_first([1, 2, 3]) first_str: str = get_first(["a", "b", "c"]) value: int = get_value({"a": 1, "b": 2}, "a")
4. 函数类型注解 4.1 Callable from typing import Callable, List # 函数作为参数 def apply_function( func: Callable[[int, int], int], a: int, b: int ) -> int: return func(a, b) # 返回函数 def create_multiplier(factor: int) -> Callable[[int], int]: def multiplier(x: int) -> int: return x * factor return multiplier # 使用示例 def add(x: int, y: int) -> int: return x + y result: int = apply_function(add, 10, 20) multiply_by_3: Callable[[int], int] = create_multiplier(3) print(multiply_by_3(5)) # 15 4.2 Lambda 函数类型 from typing import Callable # lambda 函数类型 sorter: Callable[[int, int], int] = lambda x, y: x - y numbers = [5, 2, 8, 1] sorted_numbers = sorted(numbers, key=lambda x: x) # 高阶函数 def filter_list( items: List[int], predicate: Callable[[int], bool] ) -> List[int]: return [item for item in items if predicate(item)] # 使用示例 even_numbers = filter_list([1, 2, 3, 4, 5], lambda x: x % 2 == 0)
5. 类相关的类型注解 5.1 类方法和属性 from typing import ClassVar, Final class User: # 类变量注解 count: ClassVar[int] = 0 MAX_AGE: Final[int] = 150 def __init__(self, name: str, age: int): self.name: str = name self.age: int = age User.count += 1 @classmethod def get_count(cls) -> int: return cls.count def get_info(self) -> str: return f"{self.name}, {self.age} years old" # 类型注解返回自身类型 class Node: def __init__(self, value: int): self.value: int = value self.next: Optional['Node'] = None def set_next(self, node: 'Node') -> None: self.next = node 5.2 继承和多态 from typing import Type class Animal: def speak(self) -> str: return "Animal sound" class Dog(Animal): def speak(self) -> str: return "Woof!" class Cat(Animal): def speak(self) -> str: return "Meow!" def animal_sound(animal: Animal) -> str: return animal.speak() # 工厂模式中的类型注解 def create_animal(animal_type: str) -> Animal: if animal_type == "dog": return Dog() elif animal_type == "cat": return Cat() else: return Animal() # 使用示例 dog: Animal = Dog() cat: Animal = Cat() print(animal_sound(dog)) # Woof! print(animal_sound(cat)) # Meow!
6. 高级类型注解 6.1 Literal 和 TypedDict from typing import Literal, TypedDict, List # Literal 用于字面值 def set_status(status: Literal["active", "inactive", "pending"]) -> None: print(f"Status set to: {status}") # TypedDict 用于结构化字典 class UserData(TypedDict): name: str age: int email: Optional[str] tags: List[str] def process_user(data: UserData) -> str: return f"Processing {data['name']}, age {data['age']}" # 使用示例 set_status("active") # 只能传递这三个值之一 user_info: UserData = { "name": "Alice", "age": 25, "email": "alice@example.com", "tags": ["premium", "active"] } process_user(user_info) 6.2 Protocol(结构类型) from typing import Protocol, runtime_checkable # Protocol 定义接口 class Drawable(Protocol): def draw(self) -> str: ... class Circle: def draw(self) -> str: return "Drawing Circle" class Rectangle: def draw(self) -> str: return "Drawing Rectangle" def render(shape: Drawable) -> None: print(shape.draw()) # 使用示例 circle: Drawable = Circle() rectangle: Drawable = Rectangle() render(circle) # Drawing Circle render(rectangle) # Drawing Rectangle
7. 实战示例 7.1 API 响应处理 from typing import TypedDict, List, Optional from datetime import datetime class UserResponse(TypedDict): id: int username: str email: str is_active: bool created_at: str last_login: Optional[str] class PaginatedResponse(TypedDict): count: int next: Optional[str] previous: Optional[str] results: List[UserResponse] def process_api_response(response: PaginatedResponse) -> List[str]: """处理API响应数据""" usernames: List[str] = [] for user in response['results']: if user['is_active']: usernames.append(user['username']) return usernames # 模拟API响应 api_response: PaginatedResponse = { "count": 2, "next": None, "previous": None, "results": [ { "id": 1, "username": "alice", "email": "alice@example.com", "is_active": True, "created_at": "2024-01-01", "last_login": "2024-01-14" }, { "id": 2, "username": "bob", "email": "bob@example.com", "is_active": False, "created_at": "2024-01-02", "last_login": None } ] } active_users = process_api_response(api_response) print(f"活跃用户: {active_users}") 7.2 数据验证装饰器 from typing import Callable, TypeVar, Any from functools import wraps R = TypeVar('R') def type_check(func: Callable[..., R]) -> Callable[..., R]: """类型检查装饰器""" @wraps(func) def wrapper(*args: Any, **kwargs: Any) -> R: # 获取函数的类型提示 annotations = func.__annotations__ # 检查参数类型 for i, (arg_name, arg_type) in enumerate( list(annotations.items())[:-1] # 排除返回类型 ): if i < len(args): arg_value = args[i] if not isinstance(arg_value, arg_type): raise TypeError( f"参数 '{arg_name}' 应该是 {arg_type} 类型," f"但得到的是 {type(arg_value)}" ) # 调用原函数 result = func(*args, **kwargs) # 检查返回类型 return_type = annotations.get('return') if return_type and not isinstance(result, return_type): raise TypeError( f"返回值应该是 {return_type} 类型," f"但得到的是 {type(result)}" ) return result return wrapper # 使用装饰器 @type_check def add_numbers(a: int, b: int) -> int: return a + b # 测试 try: result = add_numbers(10, 20) # 正确 print(f"结果: {result}") result = add_numbers("10", 20) # 会抛出 TypeError except TypeError as e: print(f"类型错误: {e}")
8. 工具和最佳实践 8.1 静态类型检查工具 # 安装 mypy pip install mypy # 运行 mypy 检查 mypy your_script.py # 在配置文件中启用严格模式 # pyproject.toml 或 mypy.ini """ [tool.mypy] python_version = "3.9" warn_return_any = true warn_unused_configs = true strict = true """ 8.2 最佳实践 逐步添加类型:不需要一次性为所有代码添加类型 使用合适的工具:mypy, pyright, pylance 避免过度使用 Any:尽量使用具体类型 保持一致性:团队使用相同的类型检查配置 文档补充:类型提示不能完全替代文档

上一篇     下一篇
springboot环境变量替换配置文件值

葛兰威尔均线八大法则

python 发送http请求获取行情数据实例

python 属性访问器

Python知识点及代码示例