Python 类型提示高级应用指南

1. 类型提示基础

类型提示是 Python 3.5+ 引入的一种特性,它允许我们为变量、函数参数和返回值指定类型,提高代码的可读性和可维护性。

# 基本类型提示
def add(a: int, b: int) -> int:
    return a + b

# 变量类型提示
name: str = "Alice"
age: int = 30

2. 高级类型提示

2.1 泛型类型

from typing import List, Dict, Tuple, Optional

# 列表类型
def process_numbers(numbers: List[int]) -> List[int]:
    return [n * 2 for n in numbers]

# 字典类型
def process_user(user: Dict[str, str]) -> str:
    return f"{user['name']} ({user['email']})"

# 元组类型
def get_coordinates() -> Tuple[float, float]:
    return (1.0, 2.0)

# 可选类型
def get_name(optional: Optional[str] = None) -> str:
    return optional or "Unknown"

2.2 联合类型

from typing import Union

# 联合类型
def process_value(value: Union[int, str, float]) -> str:
    return str(value)

# 联合类型与可选类型的关系
# Optional[T] 等价于 Union[T, None]

2.3 类型别名

from typing import List, Dict, TypeAlias

# 类型别名
UserId: TypeAlias = int
UserDict: TypeAlias = Dict[str, Union[str, int]]

# 使用类型别名
def get_user(user_id: UserId) -> UserDict:
    return {"id": user_id, "name": "Alice", "age": 30}

3. 泛型编程

3.1 泛型函数

from typing import TypeVar, List

T = TypeVar('T')

def reverse_list(items: List[T]) -> List[T]:
    return items[::-1]

# 使用泛型函数
print(reverse_list([1, 2, 3]))  # [3, 2, 1]
print(reverse_list(["a", "b", "c"]))  # ["c", "b", "a"]

3.2 泛型类

from typing import TypeVar, Generic

T = TypeVar('T')

class Stack(Generic[T]):
    def __init__(self):
        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(2)
print(int_stack.pop())  # 2

str_stack = Stack[str]()
str_stack.push("hello")
str_stack.push("world")
print(str_stack.pop())  # "world"

3.3 约束泛型

from typing import TypeVar, List, Protocol

class HasLength(Protocol):
    def __len__(self) -> int:
        ...

T = TypeVar('T', bound=HasLength)

def get_length(items: List[T]) -> List[int]:
    return [len(item) for item in items]

# 使用约束泛型
print(get_length(["hello", "world"]))  # [5, 5]
print(get_length([[1, 2], [3, 4, 5]]))  # [2, 3]

4. 实际应用场景

4.1 函数参数验证

from typing import List, Dict, Optional

# 类型提示用于函数参数验证
def create_user(name: str, age: int, email: Optional[str] = None) -> Dict[str, any]:
    return {
        "name": name,
        "age": age,
        "email": email
    }

# 使用函数
user = create_user("Alice", 30, "alice@example.com")
print(user)

4.2 类属性类型提示

from typing import List, Optional

class User:
    name: str
    age: int
    email: Optional[str]
    friends: List['User']  # 前向引用
    
    def __init__(self, name: str, age: int, email: Optional[str] = None):
        self.name = name
        self.age = age
        self.email = email
        self.friends = []
    
    def add_friend(self, friend: 'User') -> None:
        self.friends.append(friend)

# 使用类
user1 = User("Alice", 30)
user2 = User("Bob", 25)
user1.add_friend(user2)
print(len(user1.friends))  # 1

4.3 类型提示与静态类型检查

# 使用 mypy 进行静态类型检查
# 安装: pip install mypy
# 运行: mypy script.py

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

# 类型错误: 传入字符串
result = add("1", "2")  # mypy 会报错

5. 类型提示的最佳实践

  1. 使用具体类型:尽可能使用具体的类型,而不是 Any
  2. 使用泛型:对于集合类型,使用泛型来指定元素类型。
  3. 使用类型别名:对于复杂的类型,使用类型别名来提高可读性。
  4. 使用协议:对于需要特定方法的类型,使用协议来定义接口。
  5. 文档化类型:为类型添加文档,说明其用途和约束。
  6. 使用静态类型检查:使用 mypy 等工具进行静态类型检查。
  7. 渐进式采用:可以在现有代码中逐步添加类型提示。

6. 总结

类型提示是 Python 中一种强大的特性,它允许我们以一种清晰、明确的方式指定类型,提高代码的可读性和可维护性。通过掌握类型提示的高级应用,我们可以编写更加健壮、可维护的代码。

在实际应用中,类型提示可以用于函数参数验证、类属性类型标注、静态类型检查等多种场景,大大提高代码的质量和可维护性。

希望本文对你理解和应用 Python 类型提示有所帮助!

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐