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

@runtime_checkable 装饰器

@runtime_checkable 是 Python 的 typing 模块中的一个装饰器,用于结合 Protocol 类型,允许在运行时检查一个对象是否符合某个协议(Protocol)。它扩展了 isinstance()issubclass() 的功能,使得基于结构子类型(structural subtyping)的类型检查在运行时成为可能。


基本用法

  1. 导入装饰器

    from typing import runtime_checkable, Protocol
    
  2. 定义协议
    使用 Protocol 定义一个接口,并用 @runtime_checkable 装饰它。协议中需要声明对象必须包含的方法或属性。

    @runtime_checkable
    class SupportsClose(Protocol):
        def close(self) -> None:
            ...
    
  3. 实现类
    定义一个类,无需显式继承协议,只需实现协议中定义的方法/属性:

    class File:
        def close(self) -> None:
            print("File closed")
    
    class NetworkConnection:
        def disconnect(self) -> None:
            print("Disconnected")
    
  4. 运行时检查
    使用 isinstance() 检查对象是否符合协议:

    file = File()
    conn = NetworkConnection()
    
    print(isinstance(file, SupportsClose))  # 输出 True
    print(isinstance(conn, SupportsClose))  # 输出 False
    

关键点

  1. 结构子类型检查

    • @runtime_checkable 检查对象是否拥有协议中声明的所有方法和属性(按名称检查)。
    • 不关心继承关系,只要结构匹配即可。
  2. 仅检查存在性

    • 不会检查方法签名(参数类型、返回值类型等)。
    • 例如,协议中的方法如果有参数,但实现的方法没有参数,检查仍会通过,但调用时可能出错。
  3. 性能注意

    • 运行时检查可能影响性能,谨慎在高频代码中使用。

示例:检查属性

from typing import Protocol, runtime_checkable

@runtime_checkable
class HasName(Protocol):
    name: str  # 检查是否存在 name 属性(类型不强制)

class Person:
    def __init__(self, name: str):
        self.name = name

class Dog:
    def __init__(self):
        self.name = "Buddy"

class Car:
    def __init__(self, model: str):
        self.model = model  # 属性名不匹配

person = Person("Alice")
dog = Dog()
car = Car("Tesla")

print(isinstance(person, HasName))  # True
print(isinstance(dog, HasName))    # True
print(isinstance(car, HasName))     # False
True
True
False

常见问题

  1. 为什么 isinstance 返回 False

    • 确保协议被 @runtime_checkable 装饰。
    • 检查对象是否确实实现了协议的所有方法和属性(名称一致)。
  2. abc.ABC 的区别?

    • abc.ABC 基于继承(名义子类型),要求显式继承。
    • @runtime_checkable 基于结构子类型,无需继承。

通过 @runtime_checkable,你可以实现灵活的运行时接口检查,适用于插件系统、动态验证等场景。


文章转载自:

http://k5D3FSBy.bnLsd.cn
http://HSq59GBk.bnLsd.cn
http://JfrghtY0.bnLsd.cn
http://xPZ5Xm9d.bnLsd.cn
http://qCzr1w2Y.bnLsd.cn
http://6A801Qbh.bnLsd.cn
http://rkGqAZcA.bnLsd.cn
http://llF6Q1Ba.bnLsd.cn
http://6H2BHKNg.bnLsd.cn
http://W6dSR6gz.bnLsd.cn
http://helkhyha.bnLsd.cn
http://dDROTMPA.bnLsd.cn
http://I5StSOjh.bnLsd.cn
http://eZOLhlPU.bnLsd.cn
http://RoJc3cXO.bnLsd.cn
http://kG7oRFMg.bnLsd.cn
http://qBa3E9dB.bnLsd.cn
http://Hl5PIrlM.bnLsd.cn
http://hhkQGjSk.bnLsd.cn
http://4ykoI6J8.bnLsd.cn
http://BRROXwki.bnLsd.cn
http://2FAJFTQk.bnLsd.cn
http://0SPFGgTI.bnLsd.cn
http://aViHh5Qs.bnLsd.cn
http://6hWvEs8V.bnLsd.cn
http://ssbxSQh4.bnLsd.cn
http://m51xjIBr.bnLsd.cn
http://bXDORlIq.bnLsd.cn
http://rbaBlc2j.bnLsd.cn
http://ug7Te7MB.bnLsd.cn
http://www.dtcms.com/a/15203.html

相关文章:

  • Android WindowContainer窗口结构
  • 基于springboot 以及vue前后端分离架构的求职招聘系统设计与实现
  • TCP文件传输
  • 开发一个音响控制板程序,需要从硬件架构设计、通信协议选择、核心功能实现三个层面进行系统化开发。以下是基于工业级开发流程的实施方案
  • python-leetcode-加一
  • 【vscode】VScode Remote SSH配置
  • WPF学习笔记
  • Vue 3 30天精进之旅:Day 24 - 国际化支持
  • 如何查看 Linux 服务器的 MAC 地址:深入解析与实践指南
  • JavaScript设计模式 -- 外观模式
  • 【学习资源】时间序列数据分析方法(1)
  • Dify - 创建 RAG Workflow 及 Restful HTTP 请求
  • windows第十章 数值型关联变量和控件型关联变量
  • DeepSeek-R1论文阅读及本地调用
  • 深入理解JVM的运行时数据区
  • 【鸿蒙开发】第三十六章 状态管理 - V1V2混用和迁移指导
  • 清影2.0(AI视频生成)技术浅析(二):自然语言处理
  • Next.js【详解】获取数据(访问接口)
  • 什么是高亮环形光源
  • Vue2/Vue3分别如何使用computed
  • 深入理解Java三大特性:封装、继承和多态
  • python中的深度学习框架TensorFlow 和 PyTorch 有什么区别?
  • 调用DeepSeek API接口:实现智能数据挖掘与分析
  • 记录阿里云CDN配置
  • C语言如何实现面向对象?——从结构体到自由函数的思考
  • 分享一些处理复杂HTML结构的经验
  • 网络安全学习笔记
  • java处理pgsql的text[]类型数据问题
  • window patch按块分割矩阵
  • 大脑网络与智力:基于图神经网络的静息态fMRI数据分析方法|文献速递-医学影像人工智能进展