Python 3.7: Утилита Dataclasses и SimpleNameSpace - программирование
Подтвердить что ты не робот

Python 3.7: Утилита Dataclasses и 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 для использования?
4b9b3361

Ответ 1

Короткий ответ: все это покрывается PEP 557. Устраняя ваши вопросы немного не по порядку...

Зачем?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ответ 2

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

Dataclasses

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

SimpleNamespace

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

Из документации SimpleNamespace:

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

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

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