A class decorator is provided which inspects a class definition for
variables with type annotations as defined in PEP 526, "Syntax for
Variable Annotations". In this document, such variables are called
fields. Using these fields, the decorator adds generated method
definitions to the class to support instance initialization, a repr,
comparison methods, and optionally other methods as described in the
Specification section. Such a class is called a Data Class, but
there's really nothing special about the class: the decorator adds
generated methods to the class and returns the same class it was
given.
@dataclasses.dataclass
class RGBA:
r : int = 0
g : int = 0
b : int = 0
a : float = 1.0
def __post_init__(self):
self.a : int = int(self.a * 255)
RGBA(127, 0, 255, 0.5)
# RGBA(r=127, g=0, b=255, a=127)
遗传
@dataclasses.dataclass
class RGBA(Color):
a : int = 0
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可以将其减少为:
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
从PEP specification:
@dataclass
生成器将方法添加到类中,否则您会将这些方法定义为__repr__
、__init__
、__lt__
和__gt__
。概述
这个问题已经解决了。然而,这个答案添加了一些实际的例子来帮助对数据类的基本理解。
后一句话的意思是:
namedtuple
或常规类。与普通类相比,您主要节省了输入样板代码的时间。
特点
下面是数据类特性的概述(请参阅摘要表中的示例)。
你得到的
以下是默认情况下从数据类获得的功能。
属性+表示+比较
以下默认值将自动设置为
True
:你能打开什么
如果将适当的关键字设置为
True
,则可以使用其他功能。顺序
现在实现了排序方法(重载运算符:} 。
< > <= >=
),类似于使用更强的等式测试的^{可哈希,可变
尽管对象可能是可变的(可能是不需要的),但是实现了散列。
可哈希,不可变
现在实现了散列,不允许更改对象或分配给属性。
总的来说,如果
unsafe_hash=True
或frozen=True
,则对象是散列的。有关更多详细信息,请参见原始hashing logic table。
你得不到的
要获得以下特性,必须手动实现特殊方法:
无包装
优化
对象大小现在减小:
在某些情况下,
__slots__
还可以提高创建实例和访问属性的速度。此外,插槽不允许默认分配;否则,将引发ValueError
。有关此blog post中插槽的详细信息。
汇总表
+这些方法不是自动生成的,需要在数据类中手动实现。
*
__ne__
是not implemented。附加功能
初始化后
遗传
转换
将数据类转换为元组或dict,recursively:
限制
参考文献
数据类只是面向存储状态的常规类,而不是包含大量逻辑。每次创建一个主要由属性组成的类时,都会创建一个数据类。
dataclasses
模块所做的是使创建数据类变得更容易。它帮你处理了很多锅炉板。当数据类必须是散列的时,这一点尤其重要;这需要一个
__hash__
方法和一个__eq__
方法。如果为了便于调试而添加自定义的__repr__
方法,则可能会变得非常冗长:使用
dataclasses
可以将其减少为:同一个类decorator还可以生成比较方法(
__lt__
,__gt__
等)并处理不变性。namedtuple
类也是数据类,但默认情况下是不可变的(同时也是序列)。dataclasses
在这方面要灵活得多,并且可以很容易地构造成它们可以fill the same role as a ^{PEP的灵感来自^{} project ,它可以做更多的事情(包括插槽、验证器、转换器、元数据等)。
如果你想看一些例子,我最近为我的几个Advent of Code解决方案使用了
dataclasses
,请参见day 7、day 8、day 11和day 20的解决方案。如果要在Python版本<;3.7中使用
dataclasses
模块,则可以安装backported module(需要3.6)或使用上面提到的attrs
项目。相关问题 更多 >
编程相关推荐