002.typing类型提示


基础用法

基本类型注解

Python Typing 模块中包含了许多基本类型,包括:

可以通过在函数参数或返回值前添加类型注解来指定参数或返回值的类型。示例代码如下:

def add(x: int, y: int) -> int:
    return x + y

def concat(s1: str, s2: str) -> str:
    return s1 + s2

Union 类型注解

有时候一个参数或返回值可能有多种类型,可以使用 Union 类型注解来指定。示例代码如下:

from typing import Union

def add(x: Union[int, float], y: Union[int, float]) -> Union[int, float]:
    return x + y

add 函数接受两个参数,这两个参数可以是整数类型或浮点数类型,返回值也可以是整数类型或浮点数类型。

List、Tuple 和 Set 类型注解

可以使用 List、Tuple 和 Set 类型注解来指定一个列表、元组或集合的元素类型。示例代码如下:

from typing import List, Tuple, Set

def process_list(lst: List[int]) -> List[int]:
    return [x * 2 for x in lst]

def process_tuple(tup: Tuple[str, int, float]) -> Tuple[float, str, int]:
    return (tup[2], tup[0], tup[1])

def process_set(s: Set[str]) -> Set[str]:
    return {x.upper() for x in s}

Dict 类型注解

可以使用 Dict 类型注解来指定一个字典的键和值的类型。示例代码如下:

from typing import Dict

def process_dict(d: Dict[str, int]) -> Dict[int, str]:
    return {v: k for k, v in d.items()}

可选类型

有时我们需要指定一个类型可以为空值,这可以通过在类型注释中使用 Optional 来实现:

from typing import Optional

def get_first_item(items: Optional[List[str]]) -> Optional[str]:
    if not items:
        return None
    return items[0]

items = ["apple", "banana", "cherry"]
print(get_first_item(items))  # Output: "apple"

print(get_first_item(None))  # Output: None

Callable 类型注解

可以使用 Callable 类型注解来指定一个函数的参数和返回值类型。示例代码如下:

from typing import Callable

def process_func(f: Callable[[int, int], int], x: int, y: int) -> int:
    return f(x, y)

在上面的示例中,process_func 函数接受一个函数类型的参数 f,这个函数接受两个整数类型的参数并返回一个整数类型的值,同时还接受两个整数类型的参数 xy,返回值也是一个整数类型的值。函数体内调用了参数 f,将 xy 作为参数传递给它,并返回它的返回值。

Any 类型注解

可以使用 Any 类型注解来指定一个参数或返回值可以是任意类型。示例代码如下:

from typing import Any

def process_any(x: Any) -> Any:
    return x

类型别名

类型别名是指将一个类型定义为一个新的名称。这可以使代码更易于理解和维护。例如,我们可以使用类型别名来定义一个名为 Person 的元组类型:

from typing import Tuple

Person = Tuple[str, int]

def get_person() -> Person:
    return ("Alice", 25)

name, age = get_person()
print(name)  # Output: "Alice"
print(age)  # Output: 25

TypeVar 类型注解

TypeVar 类型注解可以用来定义一个泛型类型,表示一个类型参数。示例代码如下:

from typing import TypeVar, List

T = TypeVar('T')

def process_list(lst: List[T], f: Callable[[T], T]) -> List[T]:
    return [f(x) for x in lst]

在上面的示例中,TypeVar('T') 定义了一个类型参数 Tprocess_list 函数接受一个泛型类型的列表,和一个接受一个泛型类型参数并返回一个泛型类型的函数,返回一个泛型类型的列表,其中每个元素都被传入函数进行处理。

Generic 类型注解

Generic 类型注解可以用来定义一个泛型类型,表示一个类或函数是泛型的。示例代码如下:

from typing import TypeVar, Generic, List

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()

    def is_empty(self) -> bool:
        return len(self.items) == 0

在上面的示例中,TypeVar('T') 定义了一个类型参数 TStack(Generic[T]) 定义了一个泛型类型 Stack,这个类型接受一个类型参数 T,表示一个栈,这个栈可以存储任意类型的元素。Stack 类有三个方法:push 方法接受一个泛型类型参数 item,将它压入栈中;pop 方法弹出栈中的元素,并返回它;is_empty 方法检查栈是否为空。

Annotated 类型注解增强工具

from typing import Annotated
from pydantic import BaseModel, Field

class User(BaseModel):
    name: Annotated[str, Field(default="小明", max_length=10, description="用户名")]
    age: Annotated[int, Field(gt=18, description="用户年龄必须大于18")]

# 相当于
# name: str = Field(default="小明", max_length=10, description="用户名")
# age: int = Field(..., gt=18, description="用户年龄必须大于18")

这样做的好处: