什么是数据类,它们与普通类有何不同? [英] What are data classes and how are they different from common classes?
问题描述
通过 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天,第20天.
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屋!