当前位置: 首页 > article >正文

python 变量类型注释

文章目录

    • 1. 基础的类型注释
      • 1.1 变量类型注释
      • 1.2 函数类型注释
    • 2. 进阶使用
      • 2.1 使用 Optional 和 Union
      • 2.3 List, Tuple, Dict,Sequence 等容器类型
      • 2.4 Callable 用法
      • 2.5 类型别名
      • 2.6 NewType 用法
    • 3 总结

Python 类型注释(Type Hints)是 Python 3.5开始 引入的一项功能,旨在提高代码的可读性、可维护性,并帮助静态分析工具检查代码中的类型错误。虽然 Python 是动态类型语言,但通过类型注释,我们可以显式地标注变量和函数的预期类型,从而使代码更容易理解,并获得类型检查工具(如 mypy)的帮助。

1. 基础的类型注释

在 Python 中,类型注释通常使用 : 来指定变量或函数参数的类型,使用 -> 来指定函数返回值的类型。

1.1 变量类型注释

Python 3.6+ 支持为变量添加类型注释。它通常出现在变量赋值时,注释类型后跟 :,然后是实际的赋值操作。

x: int = 10      # x 是一个整数
y: str = "hello"  # y 是一个字符串
z: float = 3.14  # z 是一个浮动数

1.2 函数类型注释

对于函数,我们可以在函数的参数返回值上添加类型注释。参数类型注释出现在参数名后面,返回类型注释出现在函数签名的->后面。

def greet(name: str) -> str:
    return "Hello, " + name

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

在这个例子中,greet 函数接受一个字符串类型的参数 name,并返回一个字符串;add 函数接受两个整数类型的参数 a 和 b,并返回一个整数。

2. 进阶使用

2.1 使用 Optional 和 Union

有时候我们会希望一个参数或返回值是几种不同类型中的一种,这时我们可以使用 Union。如果某个值是可选的(例如,它可以是一个类型或 None),可以使用 Optional

Union 用法
Union 用于表示多种类型中的任意一种。它通常用于表示参数或返回值可以接受多种类型

from typing import Union

def process_data(data: Union[str, int]) -> str:
    if isinstance(data, str):
        return data.upper()
    elif isinstance(data, int):
        return str(data)

data 可以是一个字符串或一个整数。

Optional 用法
Optional[X] 只是 Union[X, None] 的简写形式,表示某个值可以是类型 X 或 None

from typing import Optional

def find_item(name: str) -> Optional[int]:
    # 如果找不到则返回 None,否则返回一个整数
    if name == "item1":
        return 1
    return None

在这个例子中,find_item 函数返回的值可以是 int 或 None。

案例

def get_affine_transform(
    size: Union[Tuple[float], List[float]],
    rotation: float,
    out_size: Union[Tuple[float], List[float]],
    inverse: bool = False,
    center_shift: Optional[Union[Tuple[float], List[float]]] = (0, 0),
    pre_resize_scale: Optional[float] = -1.0,
    crop_kwargs: Optional[dict] = None,
):

 def __init__(
     self,
     save_dir: str,
     name_prefix: Optional[str] = "",
     save_interval: Optional[int] = 1,
     interval_by: Optional[str] = "epoch",
     save_on_train_end: Optional[bool] = True,
     strict_match: Optional[bool] = False,
     mode: Optional[str] = None,
     monitor_metric_key: Optional[str] = None,
     best_refer_metric: Optional[Union[dict, EvalMetric]] = None,
     task_sampler=None,
     save_hash: bool = True,
     only_save_ddp: bool = False,
     keep_n: Optional[int] = None,
 ):

2.3 List, Tuple, Dict,Sequence 等容器类型

Python 允许为标准容器类型(如列表、元组、字典等)添加类型注释。可以通过 typing 模块中的类型来为容器指定具体的元素类型。

List

from typing import List,Tuple,Dict

def get_names(names: List[str]) -> int:
    return len(names)

names 是一个字符串类型的列表,函数返回一个整数。

Tuple
Tuple 用于表示固定长度、不同类型的元素的集合。

from typing import Tuple

def get_point() -> Tuple[int, int]:
    return (10, 20)

get_point 函数返回一个元组,包含两个整数。

Dict
Dict 用于表示键值对容器。

from typing import Dict

def get_person_info() -> Dict[str, str]:
    return {"name": "Alice", "age": "25"}

get_person_info 函数返回一个字典,键和值都是字符串类型。

Sequence

  • Sequence 表示一个可以被索引的容器(而不局限于列表或元组)。它使得类型更加灵活,并允许接受任何符合序列特性的数据类型。
  • Sequence 是一个更宽泛的接口,表示所有具有序列性质的对象,包括不可变的对象(如元组和字符串)以及可变对象(如列表)
from typing import List, Sequence

# List 仅限于列表
def append_to_list(lst: List[int]) -> None:
    lst.append(4)

# Sequence 可以接受任何序列类型(包括列表、元组、字符串)
def print_first(seq: Sequence[int]) -> None:
    print(seq[0])

# Test with List
lst = [1, 2, 3]
append_to_list(lst)  # 正常

# Test with Sequence
print_first(lst)  # 输出 1

案例

 def __init__(
     self,
     metric_update_func: Callable,
     metrics: Optional[Sequence] = None,
     filter_condition: Optional[Callable] = None,
     step_log_freq: Optional[int] = 1,
     reset_metrics_by: Optional[str] = "epoch",
     epoch_log_freq: Optional[int] = 1,
     log_prefix: Optional[str] = "",
     step_storage_freq: Optional[int] = -1,
     epoch_storage_freq: Optional[int] = -1,
     storage_key: Optional[str] = "monitor_obj",
 ):
def compute_box_3d_lidar(
    dim: Union[np.ndarray, List],
    location: Union[np.ndarray, List],
    yaw: np.ndarray,
    with_size: bool = False,
) -> np.ndarray:
def rearrange_det_dense_head_out(
    reg_pred: List[torch.Tensor],
    cls_pred: List[torch.Tensor],
) -> Tuple[torch.Tensor, torch.Tensor]:

2.4 Callable 用法

Callable 用于表示一个可调用对象,类似函数。你可以指定函数的参数类型和返回值类型

from typing import Callable

def execute_operation(op: Callable[[int, int], int], a: int, b: int) -> int:
    return op(a, b)

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

result = execute_operation(add, 3, 4)  # 传入 add 函数,返回 7

Callable[[int, int], int] 表示一个函数,它接受两个 int 类型的参数,并返回一个 int 类型的值。


    @abstractmethod
    def __call__(
        self,
        batch: Union[Tuple[Any], List[Any], object],
        model: torch.nn.Module,
        device: Union[int, None],
        optimizer=None,
        batch_begin_callback: Callable = None,    # 函数
        batch_end_callback: Callable = None,      # 函数
        backward_begin_callback: Callable = None,
        backward_end_callback: Callable = None,
        optimizer_step_begin_callback: Callable = None,
        optimizer_step_end_callback: Callable = None,
        forward_begin_callback: Callable = None,
        forward_end_callback: Callable = None,
    ):
    def __init__(
        self,
        model: nn.Module,
        data_loader: Iterable,
        optimizer: torch.optim.Optimizer,
        batch_processor: BatchProcessorMixin,
        device: Union[int, None],
        model_convert_pipeline: Optional[Union[Dict, List]] = None,
        resume_optimizer: bool = False,
        resume_epoch_or_step: bool = False,
        resume_dataloader: bool = False,
        stop_by: Optional[str] = "epoch",
        num_epochs: Optional[int] = None,
        start_epoch: Optional[int] = 0,
        num_steps: Optional[int] = None,
        start_step: Optional[int] = 0,
        callbacks: Optional[Sequence[Union[dict, CallbackMixin]]] = None,
        train_metrics: Optional[dict] = None,
        val_metrics: Optional[dict] = None,
        profiler: Optional[dict] = None,
        log_interval: int = 0,
        compiler: Optional[Dict] = None,
    ):

2.5 类型别名

有时,我们需要为某种复杂类型创建一个别名,以便提高代码的可读性。

from typing import List, Tuple

Coordinates = List[Tuple[int, int]]  # 类型别名,表示一组坐标点

def process_coordinates(coords: Coordinates):
    for x, y in coords:
        print(f"Processing coordinate: ({x}, {y})")

coords = [(1, 2), (3, 4), (5, 6)]
process_coordinates(coords)

2.6 NewType 用法

NewType 用于创建一个新的类型,它本质上与原类型相同,但是用于明确区分具有不同含义的相同基本类型。

from typing import NewType

UserId = NewType('UserId', int)

def get_user(user_id: UserId):
    print(f"Fetching user with ID {user_id}")

user_id = UserId(123)
get_user(user_id)

3 总结

为什么使用类型注释?

  • 可读性:类型注释可以让代码的意图更加明确。开发人员可以一眼看出一个变量或函数的预期类型。
  • 静态分析:工具如 mypy 可以静态分析 Python 代码,检查类型错误,帮助及早发现潜在的 bug。
  • IDE 支持:许多现代 IDE(如 VSCode、PyCharm)会利用类型注释提供代码补全、错误提示等功能。
  • 文档生成:类型注释可以用来生成文档,帮助其他开发者理解代码的使用。

Python 类型注释使得代码更加清晰和易于理解,能够提高代码的质量和可维护性。通过在函数、变量、容器类型、泛型等地方使用类型注释,你可以显式地声明预期的数据类型并让工具进行类型检查,从而提前发现潜在的错误。


http://www.kler.cn/a/553206.html

相关文章:

  • SQL 注入攻击
  • 神经网络|(十)概率论基础知识-正态分布及python仿真
  • EasyExcel 自定义头信息导出
  • Linux-GlusterFS进阶分布式卷
  • 华为最新OD机试真题-通过软盘拷贝文件-Python-OD统一考试(E卷)
  • Vision Transformer图像分类实现
  • Activity 任务栈 taskAffinity 用法
  • 【机器学习与数据挖掘实战】案例14:基于随机森林分类器的汽车公司客户细分预测
  • CMU 15-445 23Fall Lab 总结
  • ​33页PDF | 基于数字化转型的数据指标与标签体系应用架构设计方案
  • JavaScript 前端面试 4(作用域链、this)
  • 【nodejs+mysql2+docker】node后端开发+docker部署简记
  • 让大模型帮我设计crnn网络及可运行demo,gpt4o豆包qwendeepseek-r1
  • jenkins+docker自动发版java后端完整流程
  • draggable+el-tag 拖动元素有div宽度抖动问题
  • pycharm画图程序如何一步一步的调试
  • 技术分享:MyBatis SQL 日志解析脚本
  • Discuz! X3.5 根目录权限设置
  • 软件开源与AI开源的区别
  • Shapr3D在ipad上无法识别鼠标点击问题