跳转到主要内容

Python的记录类型

项目描述

record-type

Python的一个record类型的概念证明。

目标

  • 创建一个简单易解释的数据类型,便于初学者理解
  • 创建数据类型本身应该快速
  • 支持类型注解,但不是必需的
  • 实例是不可变的,使其(可能)可哈希
  • 支持实例实例化时Python的整个参数定义语法,并以习惯用法实现
  • 尽可能支持结构化类型(例如,基于对象的“形状”而不是继承的等价性)

示例

假设您正在跟踪商店中的商品。您可能想知道商品的名称、价格和库存数量(这是一个来自dataclasses文档的示例)。这可以用一个简单的数据类来表示,以存储所有这些信息。

record类型旨在帮助创建这样的简单数据类

from records import record

@record
def InventoryItem(name: str, price: float, *, quantity: int = 0):
    """Class for keeping track of an item in inventory."""

这创建了一个与函数实例化签名匹配的InventoryItem类。每个参数都成为被分配给参数的属性的对应名称。它还具有

  • __slots__以提高性能
  • __match_args__用于模式匹配
  • __annotations__用于运行时类型注解
  • __eq__()用于等价性
  • __hash__()用于哈希
  • __repr__()适合用于eval()
  • 不可变性

与其他方法相比

dataclasses.dataclass

您可以使用dataclass轻松创建此数据类,而不会遇到太多问题

from dataclasses import dataclass, KW_ONLY

@dataclass(frozen=True, slots=True)
class InventoryItem:
    """Class for keeping track of an item in inventory."""
    name: str
    price: float
    _: KW_ONLY
    quantity: int = 0

record相比的缺点是

  • KW_ONLY的使用很尴尬
  • 它需要使用类型注解
  • 要使其不可变(这意味着可哈希)并使用 __slots__,需要记住使用适当的参数进行选择。
  • 不支持 *args**kwargs

命名元组

collections.namedtuple

使用 namedtuple 可以快速创建类

from collections import namedtuple

InventoryItem = namedtuple("InventoryItem", ["name", "price", "quantity"])

record相比的缺点是

  • 不支持关键字唯一、位置唯一、*args**kwargs 参数。
  • 不支持类型注解。
  • 不支持 __match_args__
  • 需要支持任何返回该类实例的代码的属性和基于索引的 API。
  • 没有文档字符串。
typing.NamedTuple

可以使用 NamedTuple 创建支持命名元组的类型注解的类

from typing import NamedTuple

class InventoryItem(NamedTuple):
    """Class for keeping track of an item in inventory."""
    name: str
    price: float
    quantity: int = 0

record相比的缺点是

  • 不支持关键字唯一、位置唯一、*args**kwargs 参数。
  • 需要类型注解。
  • 不支持 __match_args__
  • 需要支持任何返回该类实例的代码的属性和基于索引的 API。

types.SimpleNamespace

可以创建一个简单的函数,该函数包装 SimpleNamespace

from types import SimpleNamespace

def InventoryItem(name: str, price: float, *, quantity: int = 0):
    return SimpleNamespace(name=name, price=price, quantity=quantity)

record相比的缺点是

  • 不支持 __slots__
  • 不支持 __match_args__
  • 没有文档字符串。
  • 没有运行时类型注解。
  • 可变(因此不可哈希)。

手动

可以手动实现等价的 record

from typing import Any, NoReturn


class InventoryItem:
    """Class for keeping track of an item in inventory."""

    __slots__ = ("name", "price", "quantity")
    __match_args__ = ("name", "price")

    name: str
    price: float
    quantity: int

    def __init__(self, name: str, price: float, *, quantity: int = 0) -> None:
        object.__setattr__(self, "name", name)
        object.__setattr__(self, "price", price)
        object.__setattr__(self, "quantity", quantity)

    def __repr__(self) -> str:
        return f"{self.__class__.__name__}({self.name!r}, {self.price!r}, quantity={self.quantity!r})"

    def __setattr__(self, _attr: Any, _val: Any) -> NoReturn:
        raise TypeError(f"{self.__class__.__name__} is immutable")

    def __eq__(self, other: Any) -> bool:
        if self.__slots__ != getattr(other, "__slots__", None):
            return NotImplemented
        return all(
            getattr(self, attr) == getattr(other, attr)
            for attr in self.__slots__
        )

    def __hash__(self) -> int:
        return hash(tuple(self.name, self.price, self.quantity))

record相比的缺点是

  • 实现起来更加冗长。

项目详情


下载文件

下载您平台的文件。如果您不确定要选择哪个,请了解有关 安装包 的更多信息。

源分布

record_type-2023.1.post1.tar.gz (6.7 kB 查看哈希值)

上传时间

构建分布

record_type-2023.1.post1-py3-none-any.whl (6.5 kB 查看哈希值)

上传时间 Python 3

由以下组织支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面