首页 > 编程问答 >如何检查具体方法是否遵守抽象方法的类型提示

如何检查具体方法是否遵守抽象方法的类型提示

时间:2024-07-31 07:12:17浏览次数:10  
标签:python python-typing mypy

这是一个由两部分组成的问题,但第二部分依赖于第一部分。

出于教育目的,我试图为 实现一个抽象基类和测试套件(概念来自抽象代数)。代数群定义的一部分相当于类型约束,我想在 ABC 上实现该类型约束,并且如果具体类上的方法不符合该约束,就会有一些抱怨。

I对于逻辑 and 下的布尔值组已经有一个首次实现,但它至少有两个问题,我希望你能帮我修复它。

from __future__ import annotations
from abc import ABC, abstractmethod


class AbsGroup(ABC):
    @abstractmethod
    def op(self, other: AbsGroup) -> AbsGroup:   # <-- Line-of-interest #1
        pass


class Bool(AbsGroup):

    def __init__(self, val="False"):

        if val not in ["True", "False"]:
            raise ValueError("Invalid Bool value %s" % val)

        self.val = val

    def op(self, other):
        """Logical AND"""
        if self.val == "True" and other.val == "True":  # <-- Line-of-interest #2
            return Bool("True")
        return Bool("False")

    def __eq__(self, other):
        return self.val == other.val

    def __repr__(self):
        return self.val

首先:兴趣线 #1 正在执行类型约束工作,但当前的实现是错误的。它仅检查该方法是否接收并返回 AbsGroup 实例。这可以是任何 AbsGroup 实例。我希望它检查它所继承的具体类,它接收并返回该具体类的实例(因此在 Bool 的情况下,它接收并返回 Bool 的实例)。该练习的重点是在一个位置执行此操作,而不是必须在每个具体类上专门设置它。我认为这是通过一些类型提示泛型完成的,这些泛型比我尚未深入研究的类型提示更深一些。我该怎么做?

第二:我如何 检查 具体方法是否符合抽象类型提示?我的 IDE (PyCharm) 中的类型检查器在感兴趣线 #2 处抱怨,因为它期望 other AbsGroup 类型,而该类型没有 val 属性。这是预料之中的,如果我能找到第一个问题的解决方案,这种情况就会消失,但我的 IDE 是我能找到的 唯一 注意到这种差异的东西。 mypy 对此事保持沉默默认,flake8 和 pylint 也是如此。 PyCharm 的功能很棒,但如果我想将其合并到工作流程中,我必须运行什么命令,如果我的具体方法不符合抽象签名,该命令会失败?


正在寻找的是 Python 中的 泛型自引用类型 。这使能够注释 AbsGroup 类,以便类型提示知道每个具体组在操作中使用其自己的类型。

以下是经过更正的代码:

from __future__ import annotations
from abc import ABC, abstractmethod
from typing import TypeVar

T = TypeVar('T', bound='AbsGroup')  # 定义一个类型变量 'T',它是 'AbsGroup' 或其子类型

class AbsGroup(ABC):
    @abstractmethod
    def op(self: T, other: T) -> T:   # 使用 'T' 进行类型提示
        pass

class Bool(AbsGroup):
    def __init__(self, val: str = "False"):
        if val not in ["True", "False"]:
            raise ValueError("Invalid Bool value %s" % val)
        self.val = val

    def op(self, other: 'Bool') -> 'Bool':  # 指定 'other' 和返回类型为 'Bool'
        """Logical AND"""
        if self.val == "True" and other.val == "True":
            return Bool("True")
        return Bool("False")

    def __eq__(self, other: 'Bool') -> bool:  # 使用 'Bool' 类型提示
        return self.val == other.val

    def __repr__(self) -> str:
        return self.val

说明:

  1. TypeVar : 我们从 typing 模块中导入 TypeVar T = TypeVar('T', bound='AbsGroup') 创建一个类型变量 T ,它表示“ AbsGroup 或其子类型”。

  2. op 方法中的 T : 在 AbsGroup op 方法中,我们现在使用 self: T, other: T) -> T 。这意味着:

  3. self 的类型为 T
  4. other 参数也必须是类型 T
  5. 该方法返回类型 T

  6. 具体类中的类型提示 : 在 Bool 类中,我们仍然提供更具体的类型提示,例如 other: 'Bool' 。但这不再是绝对必要的,因为 T 会处理这个问题,并且 IDE 和类型检查器能够推断出这一点。

类型检查:

提到 mypy 没有发现问题。可以通过运行以下命令使用 mypy 检查类型提示:

mypy your_file.py

使用更正后的代码,mypy 应该不会报告任何错误。

对于 IDE(如 PyCharm),它通常应该能够识别泛型自引用类型并提供正确的类型检查。如果 PyCharm 仍然显示错误,请确保使用的是最新版本并已启用类型提示。

其他提示:

  • 考虑使用枚举来表示布尔值,而不是字符串。这将使代码更安全、更易读。
  • 探索使用 @dataclass 装饰器来简化 Bool 类的定义。

我希望这些解释和更正后的代码能够帮助理解如何在 Python 中使用抽象基类和类型提示来实现代数群的概念!

标签:python,python-typing,mypy
From: 58694760

相关文章

  • Python:自动完成可以用于列表中的元素吗?
    Python在函数参数和函数返回类型中具有类型提示。类的元素是否有类似的东西?我希望能够在如下示例中使用自动完成功能:classMyClass:defhello(self):print("Hello")mylist=[]mylist.append(MyClass())foriinmylist:i.hello()#Noautocomplete......
  • python 中 COM 对象的正确类型提示是什么?
    我在python中使用COM对象来向3rd方软件公开可编程接口。这是通过使用Dispatchfromwin32com.client来实现的。我的项目也一直在使用python.3.7中的类型提示,但是我不确定如何为了类型提示的目的定义这些COM对象的类型。这个问题涉及我拥有的所有COM......
  • 如何遍历Python字典同时避免KeyErrors?
    解析大型JSON时,某些键可能仅在某些情况下存在,例如出现错误时。从服务器的API获取200OK的情况并不少见,但是您得到的响应包含应检查的错误。处理此问题的最佳方法是什么?我知道使用类似||之类的东西。|是处理KeyError的一种方法。get()但是如果......
  • Python 中的递归数据类型
    Python中最接近Haskell中的递归数据类型的是什么?(即在定义自身时使用类型自己的定义。)编辑:为了给出递归类型的更具体定义,下面是Haskell中的二叉树:dataTreea=Leafa|Branch(Treea)(Treea)我的阅读方式如下:二叉树可以是叶子,也可以包含两......
  • 如何在Python中平滑相邻的多边形?
    我正在寻找一种平滑多边形的方法,以便相邻/接触的多边形保持接触。单个多边形可以轻松平滑,例如使用PAEK或Bezier插值(https://pro.arcgis.com/en/pro-app/latest/tool-reference/cartography/smooth-polygon.htm),这自然会改变它们的边界边缘。但是如何平滑所有多边形......
  • Python多处理池不启动多个进程
    我正在尝试使用多处理池来创建多个进程。我有一个工作函数dummy_proc定义如下:importrefrommultiprocessingimportPooldefregex_check(input_string):#Patterntomatchboth"pm_lat"and"pm_lon_coslat"followedbytwofloatspattern=r"(c......
  • 迟滞建模作为 Python GEKKO 中 MPC 的控制约束
    我试图使用PythonGEKKO在用于控制信号调度的MPC优化问题中引入滞后约束。这已成为一项艰巨的任务,因为我无法将以下问题转换为GEKKO理解的方程。问题:如果开启时间<最短开启时间,则给定资产的控制调度不应将其关闭。如果关闭时间<最小关闭时间......
  • 在 Lambda Python 中获取 errorMessage": "期望值: 第 1 行第 1 列 (char 0)"
    我正在尝试使用slackapi和awslambda函数创建一个slack机器人。现在我只希望每当用户说“你好”时它就响应“你好”。当我在Lambda代码编辑器中测试代码时,出现此错误。我对Lambda很陌生,并且已经被困在这个问题上有一段时间了。非常感谢任何帮助!完整错误:Response......
  • 具有 Python lambda 函数的 QTimer 使用先前的数据运行
    我有一个GUI项目,它使用PySide2和Python3.8,它在QThread中执行一些后台任务。在该QThread中,我有QTimer成员对象,该对象必须定期运行一个函数,每次向其传递不同的数据。我没有使用QTimer.singleShot静态函数,因为如果需要某些特定场景,我需要......
  • 我如何在 python 上使用 spire.pdf 修复此错误
    我使用spirepdf,但出现以下错误:“DllNotFound_Windows,libSkiaSharp,Nosepuedeencontrarelmóduloespecificado.:....”defextract_text_from_pdf(file_path,output_file):#LoadaPDFdocumentdoc=PdfDocument()doc.LoadFromFile(file_path)ex......