首页 > 编程问答 >如何使用 mypy 的类型检查来强制可调用类型的签名

如何使用 mypy 的类型检查来强制可调用类型的签名

时间:2024-07-24 16:17:09浏览次数:9  
标签:python python-typing mypy

我有一个函数,它接受另一个函数 x 作为其参数。函数 x 可以有 2 种不同类型的签名,我想通过类型提示来强制执行此操作:

TYPE_A = Callable[[int, int], int]
TYPE_B = Callable[[int], int]

def my_func(x: Union[TYPE_A, TYPE_B]) -> None:
    ...determine x is of which type and use x accordingly...

我遇到了 2 个问题:

  1. 我不知道如何检查 x 是否为 TYPE_A 或 | ||。我尝试使用 TYPE_B ,它会生成类型错误。 isinstance(x, TYPE_A) 如果我使用另一种方式来确定x的类型,例如,使用

  2. 来确定x内部 signature 的签名(如果x有1 个参数或 2 个参数), my_func 每当我运行 x: mypy fromspectorimportsignature 时仍然认为存在类型错误 def my_func(x: 联合[TYPE_A, TYPE_B]): sig = 签名(x) if len(sig.parameters.values()) == 1: x(1) // mypy 认为这是一个类型错误:参数太少 别的: x(1, 2) // mypy 认为这是类型错误:参数太多

    有没有办法让我编写一个将另一个函数作为输入的函数,并使用类型检查来强制输入函数具有正确的签名?

Is there a way for me to write a function that takes another function as its input, and use type checking to enforce that the input function has the correct signature?


是对的, isinstance(x, TYPE_A) 不适用于 Callable 类型提示。这是因为 Callable 类型提示在运行时不会创建实际的类型。它们仅在类型检查期间使用。

为了解决的问题,可以使用类型守卫函数和重载。以下是如何操作:

from typing import Callable, Union, overload

TYPE_A = Callable[[int, int], int]
TYPE_B = Callable[[int], int]

@overload
def my_func(x: TYPE_A) -> None:
    ...

@overload
def my_func(x: TYPE_B) -> None:
    ...

def my_func(x: Union[TYPE_A, TYPE_B]) -> None:
    if is_type_a(x):
        # 在这里,mypy 知道 x 是 TYPE_A 类型
        x(1, 2) 
    else:
        # 在这里,mypy 知道 x 是 TYPE_B 类型
        x(1)

def is_type_a(x: Union[TYPE_A, TYPE_B]) -> bool:
    try:
        x(1, 2)
        return True
    except TypeError:
        return False

解释:

  1. 重载: 我们使用 @overload 装饰器定义了 my_func 的两个版本,每个版本接受一种类型的可调用对象。这告诉 mypy, my_func 可以接受两种不同的参数类型。

  2. 类型守卫: is_type_a 函数使用“鸭子类型”来确定 x 的类型。如果 x 可以使用两个参数调用,则它被认为是 TYPE_A 类型。

  3. 函数体: my_func 的函数体中,我们使用 is_type_a 来确定 x 的类型。根据结果,我们使用正确的参数数量调用 x

优点:

  • 类型安全: mypy 可以理解的代码,并确保在调用 x 时使用正确的参数数量。
  • 可读性: 代码更易于理解,因为每个重载函数都清楚地显示了它接受的参数类型。

注意:

  • 使用 try...except 块来确定类型并不总是理想的解决方案,因为它可能会掩盖其他错误。但是,在这种情况下,它是安全且实用的,因为它专门检查 TypeError 以区分两种 Callable 类型。

希望这可以帮助!如果还有其他问题,请随时提出。

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

相关文章

  • 将 Python 类型提示限制为元组中的值
    我的方法之一采用status中使用的filter()参数。此参数与定义如下的模型字段相关:STATUS_CHOICES=((1,_("draft")),(2,_("private")),(3,_("published")),)classMyModel(Model):status=models.PositiveSmallIntegerFi......
  • 为什么 mypy 会忽略函数中的参数错误?
    在下面的示例中,Example.__init__和f_example不带参数。因此,如果我尝试向他们传递一些参数,mypy应该发出警告。但是,当我将mypy检查应用于以下代码时,它不会发出任何警告。我犯错了吗?仅供参考,我还使用了vim和Pyright,并且如我所料,pyright警告这些错误。......
  • 在python中查找区间数据的中位数
    我正在探索不同的python库,我想知道如何找到分组数据集的近似中值。这里有一个表格供参考。年龄频率1-1012310-203502......
  • 比较Python中的字符串统一特殊字符
    也许我可以使用更好的英语,但我想要的是忽略单词中的重音(和类似的),所以:renè、rené、rene'和rene应该是相同的,所以应该mañana和manana或even-distribuited和evendistribuited,可能还有sho......
  • 如何使用 Python 脚本从客户账单电子邮件中获取订单 ID - WooCommerce API
    我想创建一个python脚本,返回只知道客户的账单电子邮件的订单。我尝试这样做,但返回所有最近的订单:fromwoocommerceimportAPIwcapi=API(url="https://siteexample.com",consumer_key="ck_xxx",consumer_secret="cs_xxx",version="wc/v3")......
  • python基础理论小总结
    1.python语言的特性Python是一门解释型语言,简单清晰,开源免费,跨平台,有大量第三方库辅助开发,支持面向对象与自动垃圾回收,方便与其他编程语言相互调用。Python在数据采集、人工智能、WEB后台开发、自动化运维、测试等方向应用广泛。2.解释型语言和编译型语言的区别执行方式不......
  • python编码规范
    本篇讲的是代码格式化的问题,解决格式化的方法在最下方,不想看内容的,滑到最下方就好了。一、变量的命名规则1.组成:字母、数字、下划线2.不可以以数字开头3.不建议使用下划线开头4.命名需见名知意5.不要与关键字重名。如何查找所有关键字?importkeywordprint(keyword.k......
  • Python爬虫开发中的常用库与框架安装指南
    在Python爬虫开发中,选择合适的库和框架可以大大提高开发效率和爬虫的性能。本文将介绍一些常用的解析库、请求库、储存库、Web库、App爬取库以及爬虫框架,并展示如何使用pip命令进行安装。一、解析库1.BeautifulSoupBeautifulSoup是一个用于从HTML或XML文件中提取数据的Pyth......
  • 如何在Python中的指定项目之后添加新项目到嵌套列表?
    给定的列表是这样的。list1=[10,20,[300,400,[5000,6000],500],30,40]预期输出是这样的。我知道这是一个非常基本的问题,但我很困惑。输出:[10,20,[300,400,[5000,6000,7000],500],30,40]我希望有人能帮助我解决这个问题。并解释了嵌套列表的插入功......
  • python带界面实现word文档比对功能
    python实现word文档比对的功能较简单,笔者这里将其界面话,可以指定输入比对的文档,相似度,最小相似参数等。输出的结果以word的形式保存,重复部分会标出,基本实现了商业软件的功能。先看界面这里不废话了,直接给出全部源码,觉得好的点个赞。程序打包的话,自己百度。fromtkinterimp......