简介
Python 中的函数注释提供了一种强大的方式,可向函数参数和返回值添加类型提示和元数据。本教程探讨了访问和利用函数注释的技术,帮助开发者提高其 Python 项目中的代码可读性、类型安全性和文档质量。
Python 中的函数注释提供了一种强大的方式,可向函数参数和返回值添加类型提示和元数据。本教程探讨了访问和利用函数注释的技术,帮助开发者提高其 Python 项目中的代码可读性、类型安全性和文档质量。
Python 中的函数注释提供了一种向函数参数和返回值添加元数据的方式。自 Python 3 引入后,它们允许开发者在不影响函数运行时行为的情况下,将任意信息附加到函数签名上。
def greet(name: str, age: int) -> str:
return f"Hello, {name}! You are {age} years old."
在这个例子中,name: str 表示 name 参数预期为字符串类型,age: int 表示整数类型,而 -> str 指定返回类型为字符串。
| 注释类型 | 描述 | 示例 |
|---|---|---|
| 参数注释 | 描述函数参数预期的类型 | def func(x: int, y: float) |
| 返回注释 | 指定预期的返回类型 | def func() -> list |
| 灵活的元数据 | 可以使用任何有效的 Python 表达式 | def func(x: "custom type") |
函数注释在以下方面特别有用:
def calculate_area(
length: float,
width: float,
unit: str = "square meters"
) -> dict[str, float]:
area = length * width
return {
"value": area,
"unit": unit
}
注释存储在函数的 __annotations__ 属性中:
def sample_function(x: int, y: str) -> bool:
pass
print(sample_function.__annotations__)
## 输出: {'x': <class 'int'>, 'y': <class'str'>,'return': <class 'bool'>}
在使用函数注释时,LabEx 建议使用 mypy 等工具进行静态类型检查,以充分发挥注释的潜力。
通过理解函数注释,Python 开发者可以编写更具自我文档性和类型感知的代码。
可以使用 __annotations__ 属性来获取函数注释,该属性提供了一个包含函数所有注释的字典。
def calculate_area(length: float, width: float) -> float:
return length * width
## 获取参数注释
print(calculate_area.__annotations__)
## 输出: {'length': <class 'float'>, 'width': <class 'float'>,'return': <class 'float'>}
def user_profile(name: str, age: int, active: bool = True) -> dict:
return {"name": name, "age": age, "active": active}
## 遍历注释
for param, annotation in user_profile.__annotations__.items():
print(f"{param}: {annotation}")
| 方法 | 描述 | 示例 |
|---|---|---|
__annotations__ |
直接字典访问 | func.__annotations__ |
inspect.signature() |
详细的函数签名 | inspect.signature(func).parameters |
typing.get_type_hints() |
解析前向引用 | typing.get_type_hints(func) |
import inspect
def complex_function(x: "int > 0", y: list[int]) -> str:
return f"Processing {x} items from {y}"
## 获取详细的注释信息
signature = inspect.signature(complex_function)
for param_name, param in signature.parameters.items():
print(f"Parameter: {param_name}")
print(f"Annotation: {param.annotation}")
from typing import get_type_hints
def process_data(items: list[int], threshold: float = 0.5) -> list[int]:
return [item for item in items if item > threshold]
## 获取类型提示
type_hints = get_type_hints(process_data)
print(type_hints)
在处理注释时,LabEx 建议使用 typing 模块进行更强大的类型处理和前向引用解析。
class DataProcessor:
def transform(self, data: list[str],
converter: callable = str.upper) -> list[str]:
return [converter(item) for item in data]
## 获取类方法注释
processor = DataProcessor()
print(processor.transform.__annotations__)
通过掌握这些注释检索技术,开发者可以更深入地了解函数类型提示和元数据。
from typing import Union, List, Dict, Callable
def process_data(
data: Union[List[int], List[str]],
transformer: Callable[[str], int] = int
) -> Dict[str, int]:
return {str(item): transformer(item) for item in data}
def validate_annotations(func):
def wrapper(*args, **kwargs):
signature = inspect.signature(func)
bound_arguments = signature.bind(*args, **kwargs)
for name, value in bound_arguments.arguments.items():
annotation = signature.parameters[name].annotation
if annotation is not inspect.Parameter.empty:
if not isinstance(value, annotation):
raise TypeError(f"{name} 必须是 {annotation} 类型")
return func(*args, **kwargs)
return wrapper
@validate_annotations
def create_user(name: str, age: int) -> dict:
return {"name": name, "age": age}
| 技术 | 描述 | 使用场景 |
|---|---|---|
| 泛型 | 参数化类型 | 复杂集合 |
| 协议 | 结构化类型 | 鸭子类型验证 |
| 具名元组 | 精确的字典类型 | 结构化数据 |
from typing import TypeVar, Generic
T = TypeVar('T')
class Repository(Generic[T]):
def __init__(self, items: List[T]):
self._items = items
def filter(self, predicate: Callable[[T], bool]) -> List[T]:
return [item for item in self._items if predicate(item)]
from __future__ import annotations
from typing import List
class TreeNode:
def __init__(self, value, children: List[TreeNode] = None):
self.value = value
self.children = children or []
在实现高级注释时,LabEx 建议使用 typing.Protocol 创建灵活的结构化类型接口。
def type_checked(func):
def wrapper(*args, **kwargs):
annotations = func.__annotations__
## 检查参数类型
for param, value in zip(func.__code__.co_varnames, args):
if param in annotations:
expected_type = annotations[param]
if not isinstance(value, expected_type):
raise TypeError(f"{param} 必须是 {expected_type} 类型")
result = func(*args, **kwargs)
## 检查返回类型
if'return' in annotations:
return_type = annotations['return']
if not isinstance(result, return_type):
raise TypeError(f"返回值必须是 {return_type} 类型")
return result
return wrapper
@type_checked
def multiply(x: int, y: int) -> int:
return x * y
from typing import Literal, TypedDict
class UserConfig(TypedDict):
username: str
role: Literal['admin', 'user', 'guest']
permissions: List[str]
def configure_user(config: UserConfig) -> None:
## 用户配置逻辑
pass
通过掌握这些高级注释技术,开发者可以创建更健壮、自我文档化且类型安全的 Python 代码。
通过掌握 Python 中的函数注释,开发者可以提高代码质量、改进类型检查,并创建更具自我文档性的代码。本教程涵盖的技术展示了如何检索、分析和利用注释数据来编写更健壮且易于维护的 Python 应用程序。