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 обслуживают?

person xssChauhan    schedule 28.06.2018    source источник
comment
SimpleNamespace добавляет только атрибуты и __repr__. dataclass добавляет гораздо больше, например __eq__, __hash__, ..   -  person L3viathan    schedule 28.06.2018


Ответы (2)


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

Почему?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

person Peter Brittain    schedule 29.06.2018
comment
Я хотел бы отметить, что это также зависит от того, насколько структурированы ваши данные. Если существует четкая модель типа / объекта, классы данных более четко определяют, что должно быть в объекте. Кроме того, такие функции классов, как __slots__, имеют больше смысла с классами данных, чем с SimpleNamespace. - person Edward Minnix; 29.06.2018
comment
@EdwardMinnix Можете ли вы написать это в качестве ответа? Это вариант использования, который стоит обсудить. - person xssChauhan; 29.06.2018

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

Классы данных

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

SimpleNamespace

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

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

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

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

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

person Edward Minnix    schedule 29.06.2018