一种出于类型检查目的而对 NamedTuple 进行子类化的方法

2024-04-17

我有一些namedtuple共享一些字段。我有一个接受这些元组的函数,并保证只与共享字段交互。我想在 mypy.txt 中对此类代码进行类型检查。

代码示例如下:

from typing import NamedTuple

class Base(NamedTuple):
    x: int
    y: int


class BaseExtended(NamedTuple):
    x: int
    y: int
    z: str

def DoSomething(tuple: Base):
    return tuple.x + tuple.y

base = Base(3, 4)
base_extended = BaseExtended(5, 6, 'foo')

DoSomething(base)
DoSomething(base_extended)

当我在此代码上运行 mypy 时,我收到一个可预测的错误:

mypy_example.py:20: 错误:“DoSomething”的参数 1 具有不兼容的类型“BaseExtended”;预期的“基地”

有没有办法构建我的代码并保持 mypy 类型检查?我无法继承BaseExtended from Base, since 有一个错误 https://github.com/python/typing/issues/427 in the NamedTuple继承实现。

我不想用丑陋的Union[Base, BaseExtended]要么,因为当我尝试键入检查时这会中断List, since List[Union[Base, BaseExtended]]不等于List[BaseExtended] due to 关于变体/协变类型的一些 mypy 魔法 https://github.com/python/mypy/issues/3351.

我应该放弃这个想法吗?


命名元组的构造方式使得继承typing.NamedTuple类目前还不可能。您必须编写自己的元类来扩展typing.NamedTupleMetaclass 使子类化工作,即使如此生成的类collections.namedtuple()只是不是为了扩展而构建的 https://stackoverflow.com/questions/28500524/python-extending-a-predefined-named-tuple/28500620#28500620.

相反,您想使用新的dataclasses module https://docs.python.org/3.7/library/dataclasses.html定义您的类并实现继承:

from dataclasses import dataclass

@dataclass(frozen=True)
class Base:
    x: int
    y: int

@dataclass(frozen=True)
class BaseExtended(Base):
    z: str

该模块是 Python 3.7 中的新模块,但您可以pip install dataclasses向后移植 https://pypi.org/project/dataclasses/#description在 Python 3.6 上。

上面定义了两个不可变类x and y属性,与BaseExtended类又添加了一个属性。BaseExtended是一个完整的子类Base,因此出于打字目的,符合以下要求DoSomething()功能。

这些类不是完整命名的元组,因为它们没有长度或支持索引,但这是通过创建继承自的基类来轻松添加的collections.abc.Sequence,添加两个通过索引访问字段的方法。如果你添加order=True to the @dataclass()装饰器然后你的实例变得完全可排序,就像(命名)元组一样:

from collections.abc import Sequence
from dataclasses import dataclass, fields

class DataclassSequence(Sequence):
    # make a dataclass tuple-like by accessing fields by index
    def __getitem__(self, i):
        return getattr(self, fields(self)[i].name)
    def __len__(self):
        return len(fields(self))

@dataclass(frozen=True, order=True)
class Base(DataclassSequence):
    x: int
    y: int

MyPy 很快就会支持dataclasses明确地 https://github.com/python/mypy/issues/4792;在 0.600 版本中,您仍然会收到错误,因为它无法识别dataclasses模块导入或__new__方法已生成。

在 Python 3.6 及更早版本中,您还可以安装attrs project http://www.attrs.org/en/stable/达到同样的效果;上面的序列基类看起来像这样使用attrs:

from collections.abc import Sequence
import attr

class AttrsSequence(Sequence):
    # make a dataclass tuple-like by accessing fields by index
    def __getitem__(self, i):
        return getattr(self, attr.fields(type(self))[i].name)
    def __len__(self):
        return len(attr.fields(type(self)))

@attr.s(frozen=True, auto_attribs=True)
class Base(AttrsSequence):
    x: int
    y: int

dataclasses是直接基于attrs, with attrs提供更多功能; mypy 完全支持使用以下命令生成的类attrs.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一种出于类型检查目的而对 NamedTuple 进行子类化的方法 的相关文章

随机推荐

  • 无法使用 mailR 包通过 Outlook.com 发送电子邮件

    我想用 mailR 用于发送带有身份验证的电子邮件通知的包 这个包的支持者是 rJava 并使用 Java 设施 我注册了 Outlook com 帐户 这是代码 library mailR email lt send mail from
  • 读取 3 个字节作为整数

    如何读取 3 个字节的整数 struct module 是否提供类似的东西 我可以读取 3 个字节并添加一个额外的 x00 然后将其解释为 4 字节整数 但这似乎没有必要 struct 模块没有 3 字节整数的选项 所以我认为附加 x00
  • 从 oauth 身份验证获取电子邮件 (Microsoft)

    如何从微软帐户获取电子邮件 我正在执行以下操作 public ActionResult ExternalLoginCallback string returnUrl AuthenticationResult result OAuthWebS
  • 在 R 中使用 geom_rect 进行时间序列着色

    我正在尝试对时间序列图的某个部分进行着色 有点像经济衰退阴影 类似于底部的图表 这篇关于 Excel 中的经济衰退阴影的文章 https research stlouisfed org tips 200511 recession bars
  • Java ArrayList 和 LinkedList - 在末尾添加元素实现细节

    我对为什么 arraylist 比链表更快的理解是 使用 arraylist 基本上只需要一个操作 更新末尾数组元素的引用 而使用链表你必须做更多的事情 例如创建一个新节点 更新 2 个引用 遍历链表并更新最后一个节点以指向新节点等 但是我
  • 如何使用函数减少值

    嘿 实际上我制作了一个 html 页面 其中有两个部分 当我单击第一部分时 数字会增加 当我单击第二部分时 第二部分中的数字会增加 我使用了 javascript 现在我在每个页面的底部做了一个按钮 我希望当我单击该按钮时 数字应该减少我尝
  • Google Drive Android API:已删除的文件夹在查询中仍然存在

    运行下面的代码 我在平板电脑上使用 Google Drive Android API 创建一个文件夹 几秒钟后 从 PC 上的远程位置删除该文件夹 当我重新运行代码时 API 仍然认为 MyFolder 存在 即使它已被删除并且在平板电脑上
  • 计算非图的所有可能突变[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我需要根据非常具体的配方构建一个非图解算器 对于每一行 我需要计算所有可能的突变 然后检查该行是否仍然使谜题有效 对于那些不知道非图的人 这
  • Xcode Storyboard 和 xib 连接

    我有一个包含许多视图控制器的故事板项目 我创建了一个名为 connecter h connector m 现在我可以将此类连接到一个 xib 文件吗 请帮我 您可以创建XIB当你创建时connector h and connector m通
  • React:如何模拟 Auth0 以使用 Jest 进行测试

    我正在使用 React react create app 和 TypeScript 使用 Auth0 进行登录 我想用 Jest 编写测试 我发现这个资源基本上是唯一谈论模拟 Auth0 对象的资源 所以我的代码如下所示 import Re
  • 如何将值从 Fragment 传递到 Activity

    我是 Android 开发新手 我试图将值从片段传递到活动 但经过多次尝试后我无法得到答案 这是我的片段 public OtpGentation int OTP this OTP OTP public OtpGentation String
  • 对行的最后一个字段进行排序

    对行列表进行排序 对每行的最后一个字段进行排序 的最简单方法是什么 每行可以有可变数量的字段 就像是 sort k 1 是我想要的 但 sort 1 不采用负数来从末尾而不是从开头选择字段 我还希望能够选择字段分隔符 编辑 要为问题添加一些
  • 在 Azure 应用服务任务 v3 中使用 Web 部署时出现 ERROR_FILE_IN_USE

    类似的问题已被问过多次 但大多数答案都是旧的 并且可能只部分适用 此问题特定于使用 Azure 应用服务部署 任务版本 3 通过 Azure DevOps Azure Pipelines 使用 Web 部署 无法将 Web 包部署到应用服务
  • 如何判断 PostgreSQL 的 Autovacuum 是否在 UNIX 上运行?

    如何判断是否自动清理守护进程在Postgres 9 x中是运行和维护数据库集群的吗 PostgreSQL 9 3 确定 Autovacuum 是否正在运行 这是 UNIX 上的 Postgres 9 3 特有的 对于 Windows 请参阅
  • 在 Codeigniter 中将数组保存到会话

    我在 Codeigniter 中将数组保存到会话数据时遇到问题 var dump this gt session gt userdata data output is boolean false array array 0 gt abc 1
  • MySQL 查询 WHERE 包括 CASE 或 IF?

    奇怪的问题 我的查询看起来像 SELECT DISTINCT ID etcetc if elses over muliple joined tables FROM table1 AS t1 some joins eventually unr
  • Ruby 1.8.7(或 Rails 2.x)中的 String.force_encoding()

    有没有解决办法可以使用String force encoding 在 Ruby 1 8 7 或 Rails 2 x 中 以便它像在 Ruby 1 9 中一样工作 我读过一些关于 require 的内容active support 但这不起作
  • WPF FrameworkElement 未接收鼠标输入

    尝试让 OnMouse 事件出现在子项中FrameworkElement 父元素是一个Panel 以及Background属性不为空 class MyFrameworkElement FrameworkElement protected o
  • 如何在 Nuxt 中导入 nuxt.config.js 中的 mdi 图标模块

    我已经安装了https materialdesignicons com https materialdesignicons com with npm install mdi font 在 nuxt config js 文件中 我不确定如何导
  • 一种出于类型检查目的而对 NamedTuple 进行子类化的方法

    我有一些namedtuple共享一些字段 我有一个接受这些元组的函数 并保证只与共享字段交互 我想在 mypy txt 中对此类代码进行类型检查 代码示例如下 from typing import NamedTuple class Base