Python 3.7: Утилита классов данных и SimpleNameSpace

Python 3.7 предоставляет новые dataclasses которые имеют предопределенные специальные функции.

С точки зрения обзора, dataclasses а также SimpleNameSpace оба обеспечивают хорошее средство инкапсуляции данных.

@dataclass
class MyData:
    name:str
    age: int

data_1 = MyData(name = 'JohnDoe' , age = 23)

data_2 = SimpleNameSpace(name = 'JohnDoe' , age = 23)

Много раз пользуюсь SimpleNameSpace просто обернуть данные и переместить их.

Я даже подкласс это добавить специальные функции:

from types import SimpleNameSpace

class NewSimpleNameSpace(SimpleNameSpace):
    def __hash__(self):
        return some_hashing_func(self.__dict__)

На мой вопрос:

  1. Как кто-то выбирает между SimpleNameSpace а также dataclasses?
  2. Почему они были необходимы, когда тот же эффект может быть достигнут с расширением SimpleNameSpace?
  3. Какие все другие варианты использования dataclasses удовлетворить?

2 ответа

Решение

Короткий ответ: все это охвачено ОПТОСОЗ 557. Принимая ваши вопросы немного не в порядке...

Зачем?

  1. Использовать PEP 526, чтобы обеспечить простой способ определения таких классов.
  2. Поддерживать статические проверки типов.

Как выбрать, когда их использовать?

PEP совершенно ясно, что они не являются заменой и ожидают, что другие решения будут иметь свое место.

Как и любое другое дизайнерское решение, вам необходимо решить, какие именно функции вам нужны. Если это включает в себя следующее, вам определенно не нужны классы данных.

Где нельзя использовать классы данных?

Требуется совместимость API с кортежами или диктовками. Требуется валидация типа, выходящая за рамки, предусмотренные PEP 484 и 526, или валидация или преобразование значения.

Тем не менее, то же самое относится и к SimpleNameSpace, так что еще мы можем посмотреть, чтобы решить? Давайте подробнее рассмотрим дополнительные функции, предоставляемые классами данных...

Существующее определение SimpleNameSpace выглядит следующим образом:

Простой подкласс объекта, который обеспечивает доступ атрибута к его пространству имен, а также значимое repr.

Затем документы Python говорят, что он обеспечивает простое __init__, __repr__ а также __eq__ реализация. Сравнивая это с PEP 557, классы данных также дают вам возможность:

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

Очевидно, что вы должны использовать классы данных, если вы заботитесь о порядке или неизменяемости (или нуждаетесь в контроле хеширования ниши).

Другие варианты использования?

Ничего такого, что я вижу, хотя вы могли бы утверждать, что первоначальное "почему?" охватывает другие случаи использования.

Очки гораздо больше похожи namedtuple и популярный пакет attrs, чем SimpleNamespace (что даже не упоминается в ПКП). Они служат двум различным целевым целям.

Dataclasses

  • структурированная
  • Типизированный (по умолчанию, но необязательно)
  • Пишет большую часть шаблонного для базовых дурных методов (__init__, __hash__, __eq__ и многое другое)
  • Обеспечить простой механизм для значений по умолчанию для атрибутов
  • Можно легко добавить __slots__ и методы

SimpleNamespace

  • Структура данных "Grab bag"
  • Используется, когда вам нужно больше, чем словарь, но меньше, чем класс
  • Не предназначен для использования таких вещей, как __slots__

От SimpleNamespace документация:

SimpleNamespace может быть полезным в качестве замены class NS: pass, Однако для структурированного типа записи используйте namedtuple() вместо.

поскольку @dataclass Предполагается заменить множество случаев использования namedtuple именованные записи / структуры должны быть сделаны с @dataclass не SimpleNamespace,

Возможно, вы также захотите взглянуть на этот доклад PyCon Раймонда Хеттингера, где он рассказывает о предыстории @dataclass и это использовать.

Другие вопросы по тегам