冻结对数据类意味着什么?
What does frozen mean for dataclasses?
@dataclass(frozen=True)
和 @dataclass(frozen=False)
有什么区别?我应该什么时候使用哪个?
在Python中,“冻结”表示无法修改对象。例如,考虑 set
和 frozenset
:
>>> s = set((1, 2, 3))
>>> s
{1, 2, 3}
>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> fs = frozenset((1, 2, 3))
>>> fs
frozenset({1, 2, 3})
>>> fs.add(4)
...
AttributeError: 'frozenset' object has no attribute 'add'
同样,用 frozen=True
创建一个 dataclass
意味着它的实例被冻结并且无法更改。
请注意,frozen
仅适用于数据类实例本身——frozen
数据类可以包含可变项,例如列表,而常规数据类可以包含 frozen/immutable 项,例如元组。
冻结对象的意义在于避免意外修改,保证值一致
- 前者有利于避免bug。当一个对象不打算被修改时,将其设置为
frozen
会通过立即错误揭示意外修改。
- 后者允许用作不可变对象,例如
dict
的键。 frozen
数据类默认是可散列的,适合作为 dict
键。
from dataclasses import dataclass
@dataclass(frozen=True)
class Frozen:
x: int
y: int
named_points = {Frozen(0, 0): "Origin"}
请注意,可哈希性不仅取决于数据类,而且是递归的——包含 list
的 frozen
数据类不可哈希,因为 list
不可哈希。
@dataclass(frozen=True)
和 @dataclass(frozen=False)
有什么区别?我应该什么时候使用哪个?
在Python中,“冻结”表示无法修改对象。例如,考虑 set
和 frozenset
:
>>> s = set((1, 2, 3))
>>> s
{1, 2, 3}
>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> fs = frozenset((1, 2, 3))
>>> fs
frozenset({1, 2, 3})
>>> fs.add(4)
...
AttributeError: 'frozenset' object has no attribute 'add'
同样,用 frozen=True
创建一个 dataclass
意味着它的实例被冻结并且无法更改。
请注意,frozen
仅适用于数据类实例本身——frozen
数据类可以包含可变项,例如列表,而常规数据类可以包含 frozen/immutable 项,例如元组。
冻结对象的意义在于避免意外修改,保证值一致
- 前者有利于避免bug。当一个对象不打算被修改时,将其设置为
frozen
会通过立即错误揭示意外修改。 - 后者允许用作不可变对象,例如
dict
的键。frozen
数据类默认是可散列的,适合作为dict
键。
from dataclasses import dataclass
@dataclass(frozen=True)
class Frozen:
x: int
y: int
named_points = {Frozen(0, 0): "Origin"}
请注意,可哈希性不仅取决于数据类,而且是递归的——包含 list
的 frozen
数据类不可哈希,因为 list
不可哈希。