В чем разница между @dataclass(frozen=True) и @dataclass(frozen=False)? Когда я должен использовать что?

0
Fl4ggi LP 14 Фев 2021 в 14:11

2 ответа

Лучший ответ

В 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'

Точно так же создание dataclass с frozen=True означает, что его экземпляры заморожены и не могут быть изменены.

Имейте в виду, что frozen применяется только к самому экземпляру класса данных - класс данных frozen может содержать изменяемые элементы, такие как списки, а обычный класс данных может содержать замороженные / неизменяемые элементы, такие как кортежи.


Цель замороженных объектов - избежать случайного изменения и гарантировать постоянное значение.

  • Первое позволяет избежать ошибок. Если объект не предназначен для изменения, включение frozen обнаруживает случайное изменение через немедленную ошибку.
  • Последний позволяет использовать в качестве неизменяемого объекта, например, ключи dict. Класс данных frozen по умолчанию хешируется и подходит в качестве ключа dict.
from dataclasses import dataclass

@dataclass(frozen=True)
class Frozen:
    x: int
    y: int

named_points = {Frozen(0, 0): "Origin"}

Обратите внимание, что хешируемость не только зависит от класса данных, но и является рекурсивной - класс данных frozen, содержащий list, не хэшируемый, потому что list не хешируется.

2
MisterMiyagi 14 Фев 2021 в 11:36

"заморожено: если истина (по умолчанию - ложь), назначение полей приведет к возникновению исключения. Это имитирует замороженные экземпляры, доступные только для чтения. Если setattr () или delattr () определена в классе, то возникает ошибка TypeError. См. обсуждение ниже "

https://docs.python.org/3/library/dataclasses.html

Поэтому всякий раз, когда вам нужны неизменяемые объекты данных, используйте frozen = true

0
Chr3is 14 Фев 2021 в 11:20
66194804