说明

在 Python 的 typing 模块中,Protocol 是一个用于定义协议(Protocol)的类。
协议是一种形式化的接口,定义了一组方法或属性的规范,而不关心具体的实现。Protocol 类提供了一种方式来定义这些协议。 使用 Protocol 类时,可以定义一个类,继承自 Protocol 并在类中定义需要的方法或属性。
这样,通过继承 Protocol,可以告诉静态类型检查器,该类遵循了特定的协议。 有点类似go语言中的interface,但又有所不同,感觉Protocol只是为了解决静态类型检查的问题

示例

from typing import Protocol

# 理解为定义接口及接口中的方法
class Animal(Protocol):
def speak(self) -> str:
pass def eat(self) -> str:
pass # 实现类,dog实现了接口中的全部方法
class Dog:
def speak(self) -> str:
return "Woof!" def eat(self) -> str:
return "Dog is eating hotdog" # 实现类,但是cat只实现了接口中的一个方法
class Cat:
def speak(self) -> str:
return "Meow!" # 参数为接口类型
def make_sound(animal: Animal) -> str:
return animal.speak() dog = Dog()
cat = Cat() # 如果单独运行,是没有问题的,所以你需要用mypy检查工具运行该代码
print(make_sound(dog)) # Output: Woof!
print(make_sound(cat)) # Output: Meow! # mypy类型检查会提示如下报错,表示Cat类没有实现接口中的eat方法
part3.py:33: error: Argument 1 to "make_sound" has incompatible type "Cat"; expected "Animal" [arg-type]
part3.py:33: note: "Cat" is missing following "Animal" protocol member:
part3.py:33: note: eat

示例2

from typing import Protocol, Any, TypeVar, TYPE_CHECKING
from collections.abc import Iterable from typing_extensions import reveal_type # 定义接口,需要实现可以比较的__lt__方法
class SupportsLessThan(Protocol):
def __lt__(self, other: Any) -> bool: ... LT = TypeVar('LT', bound=SupportsLessThan) # 表示泛型上限为SupportsLessThan def top(series: Iterable[LT], length: int) -> list[LT]: # 返回值也可以用LT,因为list也实现了__lt__方法
ordered = sorted(series, reverse=True)
return ordered[:length] if __name__ == '__main__':
fruit = 'mango pear apple kiwi banana'.split()
# tuple实现了__lt__方法
series: Iterable[tuple[int, str]] = (
(len(s), s) for s in fruit
)
length = 3
expected = [(6, 'banana'), (5, 'mango'), (5, 'apple')]
result = top(series, length) # 所以可以将series传递到top中
TYPE_CHECKING = True
if TYPE_CHECKING:
reveal_type(series)
reveal_type(expected)
reveal_type(result)
print(result == expected)

typing模块中Protocol协议的使用的更多相关文章

  1. Objective中的协议(Protocol)

    Objective中的协议(Protocol) 作用: 专门用来声明一大堆方法. (不能声明属性,也不能实现方法,只能用来写方法的声明). 只要某个类遵守了这个协议.就相当于拥有这个协议中的所有的方法 ...

  2. 分布式环境中,模块数据交互协议分析 (百度brpc)

    1. 背景 之前听到同事说,要为自己的模块考虑写个数据协议.今天有空想了一下.写出来,方便后续使用. 开源代码brpc中可以支持多种协议,nshead.redis.mongo等20多种协议. 2. 什 ...

  3. Objective-C 中的协议(@protocol)和接口(@interface)的区别

    Objective-C 中的协议(@protocol),依照我的理解,就是C#, Java, Pascal等语言中的接口(Interface).协议本身不实现任何方法,只是声明方法,使用协议的类必须实 ...

  4. VC:res协议——从模块中获取资源

    你可以从模块中获取一个资源.通过在文件名之前加上res://,你就可以引用一个嵌入在动态链接库资源文件中的HTML页面.

  5. python类型检测最终指南--Typing模块的使用

    正文共:30429 字 预计阅读时间:76分钟 原文链接:https://realpython.com/python-type-checking/ 作者:Geir Arne Hjelle 译者:陈祥安 ...

  6. python中TCP协议中的粘包问题

    TCP协议中的粘包问题 1.粘包现象 基于TCP实现一个简易远程cmd功能 #服务端 import socket import subprocess sever = socket.socket() s ...

  7. express模块中的req,res参数的常用属性方法

    express模块中的req,res参数的常用属性方法 const express = require('express'); const router = express.Router() rout ...

  8. DHCP (Dynamic Host Configuration Protocol )协议的探讨与分析

    DHCP (Dynamic Host Configuration Protocol )协议的探讨与分析 问题背景 最近在工作中遇到了连接外网的交换机在IPv6地址条件下从运营商自动获取的DNS地址与本 ...

  9. DNS 中的协议字段详细定义

    DNS中的协议字段定义 Table of Contents 1 概述 2 DNS Classes 3 DNS OpCodes 4 DNS RCODEs 5 DNS Label Types 6 DNS资 ...

  10. Objective-C( protocol协议)

    protocol 协议 protocol:用来声明方法 1.协议的定义 @protocol 协议名称 <NSObject> // 方法声明列表.... @end 2.如何遵守协议 1> ...

随机推荐

  1. [转帖]linux服务之tuned

    https://www.cnblogs.com/createyuan/p/5701650.html RHEL/CentOS 在 6.3 版本以后引入了一套新的系统调优工具 tuned/tuned-ad ...

  2. [转帖]查看x86 cpu睿频命令

    查看cpu是否开启睿频,offline掉一些cpu核心后,查看cpu睿频是否升高? turbostat统计X86 处理器的频率.空闲状态.电源状态.温度等状态等 [root@rootbird~]# t ...

  3. sed 删除包含某字符的一行 给包含某字符的一行添加 逗号的简单方法

    今天处理环境折腾死了 方法: #给包含 configdata 的一行 添加 逗号结尾 find . -name "*.json" |xargs sed -i '/configdat ...

  4. overflow的所有值,overlay不占位

    visible: 默认值.内容不会被修剪,会呈现在元素框之外. hidden: 内容会被修剪,并且其余内容是不可见的. scroll: 内容会被修剪,总是显示滚动条. auto: 内容被修剪,超出浏览 ...

  5. 【踩了一个坑】为什么 golang struct 中的 slice 无法原子赋值

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 有这样一个结构体: type MySt struct{ F ...

  6. consul系列文章01---docker安装consul

    1.下载镜像 2.运行容器 docker run --name consul -d -p 8500:8500 --restart=always  consul agent -server -boots ...

  7. Jupyter Notebook支持Go

    在执行下列命令之前,请确保你已经安装了Go和Jupyter. gophernotes是针对Jupyter和nteract的Go内核,它可以让你在基于浏览器的笔记本或桌面app上交互式地使用Go.下面介 ...

  8. vim 从嫌弃到依赖(18)——查找模式进阶

    上一篇文章中,我们初步结识了如何使用查找模式,也能够通过n和 N进行查找.这篇将会介绍搜索中更高级的用法.另外在写上一篇文章的时候我发现介绍查找相关内容的时候不能用动图来演示,主要是因为输入的内容太多 ...

  9. 14.2 Socket 反向远程命令行

    在本节,我们将继续深入探讨套接字通信技术,并介绍一种常见的用法,实现反向远程命令执行功能.对于安全从业者而言,经常需要在远程主机上执行命令并获取执行结果.本节将介绍如何利用 _popen() 函数来启 ...

  10. SpringBoot2.7集成Swagger3

    1.引入pom坐标 <!--swagger--> <dependency> <groupId>io.springfox</groupId> <ar ...