什么是数据类,它们与普通类有何不同? [英] What are data classes and how are they different from common classes?

查看:370
本文介绍了什么是数据类,它们与普通类有何不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过 PEP 557 数据类被引入python标准库.

With PEP 557 data classes are introduced into python standard library.

它们使用@dataclass装饰器,并且应该是带有默认值的可变命名元组",但是我不确定我是否真正理解这是什么意思,以及它们与普通类的区别.

They make use of the @dataclass decorator and they are supposed to be "mutable namedtuples with default" but I'm not really sure I understand what this actually means and how they are different from common classes.

什么是python数据类,什么时候最好使用它们?

What exactly are python data classes and when is it best to use them?

推荐答案

数据类只是用于存储状态的常规类,它不仅包含许多逻辑.每次创建一个主要由属性组成的类时,就创建了一个数据类.

Data classes are just regular classes that are geared towards storing state, more than contain a lot of logic. Every time you create a class that mostly consists of attributes you made a data class.

dataclasses模块的作用是使更容易来创建数据类.它会为您处理很多样板.

What the dataclasses module does is make it easier to create data classes. It takes care of a lot of boiler plate for you.

当您的数据类必须是可哈希的时,这尤其重要.这需要__hash__方法和__eq__方法.如果您添加自定义__repr__方法以简化调试,则可能会变得很冗长:

This is especially important when your data class must be hashable; this requires a __hash__ method as well as an __eq__ method. If you add a custom __repr__ method for ease of debugging, that can become quite verbose:

class InventoryItem:
    '''Class for keeping track of an item in inventory.'''
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def __init__(
            self, 
            name: str, 
            unit_price: float,
            quantity_on_hand: int = 0
        ) -> None:
        self.name = name
        self.unit_price = unit_price
        self.quantity_on_hand = quantity_on_hand

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand

    def __repr__(self) -> str:
        return (
            'InventoryItem('
            f'name={self.name!r}, unit_price={self.unit_price!r}, '
            f'quantity_on_hand={self.quantity_on_hand!r})'

    def __hash__(self) -> int:
        return hash((self.name, self.unit_price, self.quantity_on_hand))

    def __eq__(self, other) -> bool:
        if not isinstance(other, InventoryItem):
            return NotImplemented
        return (
            (self.name, self.unit_price, self.quantity_on_hand) == 
            (other.name, other.unit_price, other.quantity_on_hand))

使用dataclasses,您可以将其缩小为:

With dataclasses you can reduce it to:

from dataclasses import dataclass

@dataclass(unsafe_hash=True)
class InventoryItem:
    '''Class for keeping track of an item in inventory.'''
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand

同一类装饰器还可以生成比较方法(__lt____gt__等)并处理不可变性.

The same class decorator can also generate comparison methods (__lt__, __gt__, etc.) and handle immutability.

namedtuple类也是数据类,但是默认情况下是不变的(以及作为序列). dataclasses在这方面更加灵活,并且可以轻松地进行结构化,以使它们可以

namedtuple classes are also data classes, but are immutable by default (as well as being sequences). dataclasses are much more flexible in this regard, and can easily be structured such that they can fill the same role as a namedtuple class.

PEP的灵感来自 attrs项目,该项目甚至可以做更多(包括广告位,验证器,转换器,元数据等).

The PEP was inspired by the attrs project, which can do even more (including slots, validators, converters, metadata, etc.).

如果您想看一些示例,我最近在 Advent of Code 解决方案中使用了dataclasses,请参阅第7天第8天

If you want to see some examples, I recently used dataclasses for several of my Advent of Code solutions, see the solutions for day 7, day 8, day 11 and day 20.

如果要在Python版本中使用dataclasses模块< 3.7,则可以安装反向移植的模块(需要3.6)或使用上述的attrs项目

If you want to use dataclasses module in Python versions < 3.7, then you could install the backported module (requires 3.6) or use the attrs project mentioned above.

这篇关于什么是数据类,它们与普通类有何不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆