Python类型注解全解析

部署运行你感兴趣的模型镜像

        类型注解是 Python 3.5+ 引入的特性,允许为变量、函数参数和返回值等添加类型提示,提高代码的可读性和可维护性。

基础类型注解

变量类型注解

# 基础类型
name: str = "Alice"
age: int = 25
height: float = 1.75
is_student: bool = True

# 集合类型
from typing import List, Dict, Set, Tuple

numbers: List[int] = [1, 2, 3, 4, 5]
person: Dict[str, str] = {"name": "Bob", "city": "New York"}
unique_ids: Set[int] = {1, 2, 3, 4}
coordinates: Tuple[float, float] = (40.7128, -74.0060)

函数类型注解

def greet(name: str) -> str:
    return f"Hello, {name}"

def calculate_area(length: float, width: float) -> float:
    return length * width

def process_data(
    data: List[int], 
    multiplier: float = 1.0
) -> Dict[str, float]:
    return {
        "sum": sum(data) * multiplier,
        "average": (sum(data) / len(data)) * multiplier
    }

高级类型注解

可选类型 (Optional)

from typing import Optional, Union

def find_user(user_id: int) -> Optional[str]:
    """可能返回字符串,也可能返回None"""
    users = {1: "Alice", 2: "Bob"}
    return users.get(user_id)

# 等价写法
def find_user_v2(user_id: int) -> Union[str, None]:
    users = {1: "Alice", 2: "Bob"}
    return users.get(user_id)

联合类型 (Union)

from typing import Union

def process_value(value: Union[int, str, float]) -> str:
    """接受多种类型的参数"""
    return str(value)

# Python 3.10+ 的简化写法
def process_value_v2(value: int | str | float) -> str:
    return str(value)

任意类型 (Any)

from typing import Any

def flexible_function(data: Any) -> Any:
    """接受和返回任意类型"""
    return data

复杂数据结构注解

嵌套类型

from typing import List, Dict, Tuple, Optional

# 复杂的嵌套结构
UserProfile = Dict[str, Union[str, int, List[str]]]
Coordinates = Tuple[float, float]

def create_user_profile(
    name: str, 
    age: int, 
    hobbies: List[str],
    location: Optional[Coordinates] = None
) -> UserProfile:
    profile = {
        "name": name,
        "age": age,
        "hobbies": hobbies,
        "is_active": True
    }
    if location:
        profile["location"] = location
    return profile

类类型注解

class Person:
    def __init__(self, name: str, age: int) -> None:
        self.name: str = name
        self.age: int = age
    
    def get_birth_year(self) -> int:
        from datetime import datetime
        return datetime.now().year - self.age

def create_people() -> List[Person]:
    return [Person("Alice", 25), Person("Bob", 30)]

泛型和类型变量

from typing import TypeVar, Generic, List

T = TypeVar('T')  # 任意类型
U = TypeVar('U')  # 另一个任意类型

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] = Stack()
int_stack.push(1)
int_stack.push(2)

str_stack: Stack[str] = Stack()
str_stack.push("hello")

函数类型和回调

from typing import Callable, List

# 函数类型注解
MathOperation = Callable[[float, float], float]

def apply_operation(
    numbers: List[float],
    operation: MathOperation
) -> List[float]:
    return [operation(x, x) for x in numbers]

def multiply(a: float, b: float) -> float:
    return a * b

result = apply_operation([1, 2, 3], multiply)

现代 Python 类型特性 (3.8+)

字面量类型 (Literal)

from typing import Literal

HttpMethod = Literal["GET", "POST", "PUT", "DELETE"]

def make_request(
    method: HttpMethod, 
    url: str
) -> None:
    print(f"Making {method} request to {url}")

# 正确使用
make_request("GET", "https://example.com")
# make_request("PATCH", "https://example.com")  # 类型检查会报错

最终类型 (Final)

from typing import Final

# 常量注解
MAX_SIZE: Final[int] = 100
DEFAULT_NAME: Final[str] = "Unknown"

class Database:
    # 类常量
    TIMEOUT: Final[int] = 30

数据类 (dataclass) 类型注解

from dataclasses import dataclass
from typing import List, Optional

@dataclass
class User:
    name: str
    age: int
    email: Optional[str] = None
    tags: List[str] = None
    
    def __post_init__(self):
        if self.tags is None:
            self.tags = []

# 使用数据类
user = User(name="Alice", age=25, email="alice@example.com")

类型检查工具

使用 mypy 进行类型检查

# 安装 mypy
pip install mypy

# 检查单个文件
mypy your_script.py

# 检查整个项目
mypy your_project/

# 严格模式
mypy --strict your_script.py

配置 mypy

在 pyproject.toml 或 mypy.ini 中配置:

[tool.mypy]
python_version = "3.8"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true

实际应用示例

from typing import List, Dict, Optional, Union
from datetime import datetime

class Order:
    def __init__(
        self, 
        order_id: str, 
        items: List[Dict[str, Union[str, int, float]]],
        customer_email: str,
        created_at: Optional[datetime] = None
    ) -> None:
        self.order_id = order_id
        self.items = items
        self.customer_email = customer_email
        self.created_at = created_at or datetime.now()
    
    def get_total_price(self) -> float:
        return sum(item.get('price', 0) * item.get('quantity', 1) 
                  for item in self.items)
    
    def to_dict(self) -> Dict[str, Union[str, float, List]]:
        return {
            "order_id": self.order_id,
            "total_price": self.get_total_price(),
            "items": self.items,
            "created_at": self.created_at.isoformat()
        }

def process_orders(
    orders: List[Order], 
    discount: float = 0.0
) -> Dict[str, float]:
    """处理订单并返回统计信息"""
    total_revenue = sum(order.get_total_price() * (1 - discount) 
                       for order in orders)
    
    return {
        "total_orders": len(orders),
        "total_revenue": total_revenue,
        "average_order_value": total_revenue / len(orders) if orders else 0
    }

最佳实践

  1. 逐步引入: 在现有项目中逐步添加类型注解

  2. 保持一致性: 团队中使用统一的类型注解风格

  3. 合理使用 Any: 尽量避免过度使用 Any 类型

  4. 利用工具: 使用 mypy 等工具进行静态类型检查

  5. 文档补充: 类型注解不能完全替代文档,复杂逻辑仍需注释

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值