首页 > 编程问答 >如何在通用 Python 类中输入 __eq__ ?

如何在通用 Python 类中输入 __eq__ ?

时间:2024-08-08 04:35:02浏览次数:11  
标签:python python-typing pyright

当我定义带有泛型类型参数的类型时(例如 K / V 映射的键和值),我似乎无法编写合适的 isinstance 检查来实现 __eq__

from collections import OrderedDict
from collections.abc import MutableMapping
from typing import TypeVar

K = TypeVar("K")
V = TypeVar("V")

class MyDictWrapper(MutableMapping[K, V]):

  def __init__(self):
    self.cache: OrderedDict[K, V] = OrderedDict()

  def __eq__(self, other: object) -> bool:
    if not isinstance(other, MyDictWrapper):
      return NotImplemented
    return self.cache == other.cache  # Pyright error: Type of "cache" is partially unknown: Type of "cache" is "OrderedDict[Unknown, Unknown]

(这是关于 pyright 1.1.309 ,请参阅 Pyright Playground 重现 )

替代方案

    if not isinstance(other, MyDictWrapper[K, V]):

也不起作用,错误如下:

Second argument to "isinstance" must be a class or tuple of classes
  Generic type with type arguments not allowed for instance or class 

是否有正确的方法来输入此内容?


你不能用 isinstance 来检查类型参数,Python 中的泛型主要在运行时被删除。但是,你可以通过以下方式解决这个问题:

  1. 鸭子类型: 不要显式检查类型,而是检查所需的行为。在你的情况下,这意味着检查 other 对象是否具有一个名为 cache 的属性,并且该属性的行为像一个 OrderedDict
from collections import OrderedDict
from collections.abc import MutableMapping
from typing import TypeVar

K = TypeVar("K")
V = TypeVar("V")

class MyDictWrapper(MutableMapping[K, V]):
    def __init__(self):
        self.cache: OrderedDict[K, V] = OrderedDict()

    def __eq__(self, other: object) -> bool:
        if not hasattr(other, "cache"):
            return NotImplemented
        # 检查 other.cache 是否是 OrderedDict 或具有相同接口的对象
        try:
            return self.cache == other.cache 
        except TypeError:
            return False
  1. 使用 typing.Protocol (Python 3.8+): 你可以定义一个协议来描述你期望的行为,然后使用 isinstance 来检查它。这在运行时仍然不起作用,但它可以帮助类型检查器理解你的意图:
from collections import OrderedDict
from collections.abc import MutableMapping
from typing import TypeVar, Protocol

K = TypeVar("K")
V = TypeVar("V")

class Cacheable(Protocol):
    cache: OrderedDict

class MyDictWrapper(MutableMapping[K, V]):
    def __init__(self):
        self.cache: OrderedDict[K, V] = OrderedDict()

    def __eq__(self, other: object) -> bool:
        if not isinstance(other, Cacheable):
            return NotImplemented
        return self.cache == other.cache

请记住,这两种方法主要用于类型检查。在运行时,Python 不会强制执行泛型类型参数,因此你仍然需要小心处理潜在的类型错误。

标签:python,python-typing,pyright
From: 77923461

相关文章

  • 无法使用 devstack 安装 openstack 因为 python 版本
    我正在使用默认的python3.8.10运行./stack.sh,我收到此错误,因为我需要3.9或更高版本3.8msg错误但是当我将默认版本更改为3.9时,我收到错误没有找到模块“apt_pkg”3.9msgerror我一直在em之间来回跳动,但错误仍然存​​在(我也每次都会检查版本)......
  • Python @overload 使用联合类型会导致函数签名重叠错误
    我想编写以下重载的Python函数:fromtypingimportAny,TypeVar,overload_T1=TypeVar('_T1')_T2=TypeVar('_T2')_T3=TypeVar('_T3')@overloaddefparse_as(ty:type[_T1]|type[_T2],s:bytes)->_T1|_T2:...@overload......
  • python joblib.load 发生错误:协议 0 中的持久 ID 必须是 ASCII 字符串 在 GCP 云运行
    总体而言:我尝试使用Cloudbuild和Cloudrun构建BERT模型。我将模型(参数)和元数据(标签)保存在GCPCloudStorage中。但是,我遇到了通过joblib.load()加载metadata.bin文件的错误。我的metadata.bin文件包含UTF-8字符,但joblib.load需要ASCII字符。在......
  • Python + Svelte,如何使用本地文件系统
    总结一下,我有一个用python编写的应用程序。它在输入时需要一堆视频文件。使用一些魔法并生成合并的视频文件输出。我没有找到一个好的GUI解决方案(tkinter,QT,TUI等),所以我选择Svelte框架。但是出现了一个问题,我如何使用本地文件系统。在GUI(svelte)上,我必须上......
  • 如何在Python中绘制伪球面
    目标是使用meshgrid和numpy库生成伪球体的三维图形,但我使用下面的代码生成的图形不完整u=np.linspace(0,np.pi,50)v=np.linspace(0,2*np.pi,100)x,y=np.meshgrid(u,v)X=np.arccos(x)*np.cos(y)Y=np.arccos(x)*np.sin(y)Z=x-np.tan(x)fig=plt.f......
  • 18:Python集合属性
    #Python3集合#集合(set)是一个无序的不重复元素序列。#集合中的元素不会重复,并且可以进行交集、并集、差集等常见的集合操作。#集合中元素必须是不可变类型,也就说里面不能是列表和字典#可以使用大括号{}创建集合,元素之间用逗号,分隔,或者也可以使用set()函数创建集合。s......
  • Python爬虫案例与实战:爬取源代码练习评测结果
    Python爬虫案例与实战:爬取源代码练习评测结果本章案例将介绍用Python编写程序实现简单网站的模拟登录,然后保持登录后的网页会话,并在会话中模拟网页表单提交,之后使用Requests库的高级特性爬取提交之后的返回结果。在HTTP网页中,如登录、提交和上传等操作一般通过向网页发送......
  • Python爬虫案例与实战:爬取豆瓣电影简介
    Python爬虫案例与实战:爬取豆瓣电影简介本章案例将介绍如何爬取豆瓣电影简介,以此帮助读者学习如何通过编写爬虫程序来批量地从互联网中获取信息。本案例中将借助两个第三方库----Requests库和BeautifulSoup库。通过Requests库获取相关的网页信息,通过BeautifulSoup库解析大......
  • 趣味Python游戏编程:第3章 递归函数的威力:扫雷
    趣味Python游戏编程:第3章递归函数的威力:扫雷在第2章中,我们制作了一个拼图游戏,玩家通过鼠标操作图片块移动。本章设计一款扫雷游戏,玩法是在一个方块阵列中随机埋设一定数量的地雷,然后由玩家逐个打开方块,并以排除所有地雷为最终游戏目标。如果玩家打开的方块中有地雷,则游戏......
  • Python 依赖管理神器 Poetry 深入指南
    Poetry依赖管理详细教程引言在现代软件开发中,依赖管理是项目成功的关键。Python开发者现在有了一个新的选择:Poetry。Poetry是一个现代的Python包管理工具,旨在简化Python项目的创建、打包和发布。它提供了一种更直观和高效的方式来管理项目的依赖关系,相较于传统的p......