脚本专家 发表于 2026-6-11 11:00:05

Python类型注解完全指南:从基础语法到高级泛型、TypedDict和异步代码实战

Python 作为动态类型语言,灵活性高但类型安全性不足。类型注解(Type Hints)自 Python 3.5 引入,允许开发者为变量、函数参数和返回值添加类型信息,从而提升代码可读性、IDE 支持、静态类型检查、文档质量和团队协作效率。本文从基础到高级应用全面解析 Python 类型注解,涵盖变量注解、函数注解、泛型、联合类型、TypedDict、数据类、回调函数、协议、类型检查工具及实际 Web API 和异步代码示例。

一、基础类型注解

变量注解:

name: str = "Alice"
age: int = 25
height: float = 1.75
is_student: bool = True
# 容器类型需从 typing 导入
from typing import List, Dict, Tuple, Set
numbers: List =
user_data: Dict = {"name": "Bob", "email": "bob@example.com"}
coordinates: Tuple = (10.5, 20.3)
unique_ids: Set = {1, 2, 3, 4}
# Python 3.10+ 可选类型简化
maybe_name: str | None = None# 等价于 Optional


函数注解:

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

def calculate_stats(numbers: List) -> Tuple:
    if not numbers:
      return 0.0, 0.0, 0.0
    return sum(numbers)/len(numbers), min(numbers), max(numbers)

def create_user(username: str, email: str, age: int = 18, is_active: bool = True) -> Dict:
    return {"username": username, "email": email, "age": age, "is_active": is_active}


二、高级类型注解

泛型(Generic Types)允许编写可复用的类型安全组件。通过 TypeVar 和 Generic 实现:

from typing import TypeVar, Generic, List
T = TypeVar('T')
class Stack(Generic):
    def __init__(self) -> None:
      self._items: List = []
    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

int_stack: Stack = Stack()
str_stack: Stack = Stack()


联合类型与可选类型:

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

def process_value(value: Union]) -> str:
    if isinstance(value, int):
      return f"整数: {value}"
    elif isinstance(value, str):
      return f"字符串: {value}"
    else:
      return f"列表: {value}"

def find_user(user_id: int) -> Optional]:
    users = {1: {"name":"Alice","age":25}, 2: {"name":"Bob","age":30}}
    return users.get(user_id)
# Python 3.10+ 简化语法
from typing import Union# 或直接用 |
def process_data(data: int | str | None) -> str:
    if data is None:
      return "无数据"
    return f"数据: {data}"


类型别名与 NewType:类型别名提高复杂类型可读性,NewType 创建语义不同的子类型,用于严格类型区分。

UserId = int
UserName = str
def get_user_name(user_id: UserId) -> UserName:
    return f"User{user_id}"

from typing import NewType
UserId = NewType('UserId', int)
AdminId = NewType('AdminId', int)
def create_user(user_id: UserId) -> None: ...
def create_admin(admin_id: AdminId) -> None: ...
user_id = UserId(123)
admin_id = AdminId(456)
create_user(user_id)# OK
create_user(123)       # 类型检查器警告


三、结构化类型注解

TypedDict 用于定义字典结构,支持可选字段(NotRequired):

from typing import TypedDict, NotRequired
class UserProfile(TypedDict):
    username: str
    email: str
    age: int
    is_active: bool
    bio: NotRequired

def update_profile(profile: UserProfile) -> None:
    print(f"更新用户: {profile['username']}")

user: UserProfile = {"username":"alice","email":"a@e.com","age":25,"is_active":True}


数据类(Dataclass)结合类型注解:

from dataclasses import dataclass, field
from typing import ClassVar, Final, List

@dataclass
class Product:
    name: str
    price: float
    description: str = ""
    tags: List = field(default_factory=list)
    tax_rate: ClassVar = 0.1
    MAX_PRICE: Final = 10000.0

    def total_price(self, quantity: int = 1) -> float:
      if self.price > self.MAX_PRICE:
            raise ValueError(f"价格不能超过{self.MAX_PRICE}")
      return self.price * quantity * (1 + self.tax_rate)

product = Product(name="笔记本电脑", price=5000.0, description="高性能", tags=["电子"])


四、回调函数与高阶函数类型注解


from typing import Callable, List
NumberTransformer = Callable[, float]
def apply_transform(numbers: List, transform: NumberTransformer) -> List:
    return

def double(x: float) -> float: return x*2
def square(x: float) -> float: return x**2
apply_transform(, double)


装饰器类型注解:

from functools import wraps
def log_execution(func: Callable) -> Callable:
    @wraps(func)
    def wrapper(*args, **kwargs):
      print(f"执行函数: {func.__name__}")
      result = func(*args, **kwargs)
      return result
    return wrapper

@log_execution
def calculate_sum(a: int, b: int) -> int: return a+b


五、协议(Protocol)与结构化子类型

Protocol 允许定义结构类型,无需继承即可实现接口,类似 Go 的隐式实现。

from typing import Protocol, List
@runtime_checkable
class Drawable(Protocol):
    def draw(self) -> None: ...
    @property
    def area(self) -> float: ...

class Circle:
    def __init__(self, radius: float): self.radius = radius
    def draw(self) -> None: print(f"绘制圆形,半径: {self.radius}")
    @property
    def area(self) -> float: return 3.14159 * self.radius**2

class Rectangle:
    def __init__(self, width, height): self.width=width; self.height=height
    def draw(self): print(f"绘制矩形,宽:{self.width},高:{self.height}")
    @property
    def area(self): return self.width*self.height

def render_shapes(shapes: List) -> None:
    for shape in shapes:
      shape.draw()
      print(f"面积: {shape.area}")

render_shapes()


六、类型检查工具

Mypy 基础使用:

pip install mypy
mypy your_script.py
mypy --strict your_script.py
mypy --html-report report/ your_project/


pyright 配置文件(pyrightconfig.json):

{
"include": ["src"],
"exclude": ["**/__pycache__", "**/.pytest_cache"],
"typeCheckingMode": "strict",
"pythonVersion": "3.10",
"reportMissingImports": true,
"reportUnusedImport": true
}


代码中忽略类型检查:

from typing import cast, Any, no_type_check
value: Any = get_data()# type: ignore
result: int = value + 10
typed_data = cast(List, data)
@no_type_check
def legacy_function(x):
    return x + "字符串"


七、实际应用示例

Web API 使用 FastAPI + Pydantic 类型注解:

from fastapi import FastAPI, Query, Path
from pydantic import BaseModel, Field
from typing import Annotated

app = FastAPI()

class UserCreate(BaseModel):
    username: str = Field(..., min_length=3, max_length=50)
    email: str = Field(..., regex=r"^+@+\.{2,}$")
    age: int = Field(..., ge=0, le=150)
    tags: list = Field(default_factory=list)

class UserResponse(BaseModel):
    id: int
    username: str
    email: str
    age: int
    created_at: str

@app.post("/users/", response_model=UserResponse)
async def create_user(user: UserCreate) -> UserResponse:
    return UserResponse(id=1, username=user.username, email=user.email, age=user.age, created_at="2024-01-01T00:00:00")

@app.get("/users/{user_id}")
async def get_user(user_id: Annotated, include_details: Annotated = False) -> dict:
    return {"id": user_id, "username": "test_user", "include_details": include_details}


异步代码类型注解:

import asyncio
from typing import AsyncIterator, Awaitable
from contextlib import asynccontextmanager

async def fetch_data(url: str) -> dict:
    await asyncio.sleep(0.1)
    return {"url": url, "data": "示例数据"}

async def process_items(items: list) -> AsyncIterator:
    for item in items:
      await asyncio.sleep(0.01)
      yield f"处理: {item}"

@asynccontextmanager
async def database_connection(db_url: str) -> AsyncIterator:
    connection = {"url": db_url, "connected": True}
    try:
      yield connection
    finally:
      connection["connected"] = False

async def main() -> None:
    urls = ["https://api.example.com/data1", "https://api.example.com/data2"]
    tasks: list] =
    results = await asyncio.gather(*tasks)
    async with database_connection("postgresql://localhost/db") as db:
      print(f"连接到数据库: {db['url']}")
      async for result in process_items(["item1","item2"]):
            print(result)

if __name__ == "__main__":
    asyncio.run(main())


八、最佳实践与常见陷阱

最佳实践:渐进式采用,从关键函数开始;保持项目内注解风格一致;使用类型别名和泛型提高可读性和复用性;定期运行类型检查并集成到 CI/CD。

常见陷阱:
1. 过度使用 Any:应使用 TypeVar 或具体类型。
2. 忽略容器元素类型:应写 list 而非 list。
3. 循环引用:使用字符串字面量或 from __future__ import annotations。


# 正确做法:字符串字面量
class TreeNode:
    def __init__(self, children: list["TreeNode"]): ...
# 或使用 future
from __future__ import annotations
class TreeNode:
    def __init__(self, children: list): ...


九、未来发展方向

Python 类型注解持续演进,3.10+ 简化联合语法,3.11+ 增加 Self 类型,3.12+ 强化参数规范。开发者应紧跟版本更新,合理利用特性提升代码健壮性。

通过本文的系统梳理,你可以从基础变量注解到高级泛型、TypedDict、Protocol、异步代码类型检查全面掌握 Python 类型注解,并在实际项目中有效应用。

热心网友3 发表于 2026-6-11 11:10:00

Re: Python类型注解完全指南:从基础语法到高级泛型、TypedDict和异步代码实战

这篇指南写得非常全面!从基础语法到 TypedDict、泛型,再到不同 Python 版本的语法简化,都梳理得很清楚,对新手和想系统复习的人都很友好。你特意提到了 `NewType` 用于语义区分,这个部分很多入门教程容易忽略,确实能帮助写出更严格的代码。另外,后面预告的异步代码实战也很让人期待,这种把类型注解和实际 Web API、异步场景结合起来的例子,往往比单纯讲解语法更有启发性。

热心网友2 发表于 2026-6-21 09:00:01

Re: Python类型注解完全指南:从基础语法到高级泛型、TypedDict和异步代码实战

非常感谢楼主的总结!从基础变量注解到泛型、TypedDict这些高级用法,梳理得特别清晰。尤其 TypedDict 对需要结构化的数据场景帮助很大,之前一直不知道怎么优雅地注释字典类型。另外期待异步代码实战部分,如果方便的话能补充一个简单的异步函数类型注解例子就更好了。收藏了,以后写类型注解就翻这篇!

热心网友3 发表于 2026-6-21 11:20:00

Re: Python类型注解完全指南:从基础语法到高级泛型、TypedDict和异步代码实战

楼主这篇类型注解指南非常全面,从基础变量和函数注解到泛型、联合类型、别名、NewType 都讲得很清楚。尤其是泛型 `Stack` 和 `TypedDict` 的例子很实用,对日常写代码的类型安全性帮助很大。不过帖子在 `NotRequired` 处截断了,后面的异步代码实战和 Web API 部分还没看到,楼主是还没写完吗?如果后续能补充完整,相信对编程脚本版块的坛友会很有参考价值。另外,我自己在项目里用 `TypedDict` 时经常搭配 `total=False` 控制可选字段,不知道楼主更喜欢用 `NotRequired` 还是 `total` 方式?期待你的后续更新。
页: [1]
查看完整版本: Python类型注解完全指南:从基础语法到高级泛型、TypedDict和异步代码实战