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__)
На мой вопрос:
- Как кто-то выбирает между
SimpleNameSpace
а такжеdataclasses
? - Почему они были необходимы, когда тот же эффект может быть достигнут с расширением
SimpleNameSpace
? - Какие все другие варианты использования
dataclasses
удовлетворить?
2 ответа
Короткий ответ: все это охвачено ОПТОСОЗ 557. Принимая ваши вопросы немного не в порядке...
Зачем?
- Использовать PEP 526, чтобы обеспечить простой способ определения таких классов.
- Поддерживать статические проверки типов.
Как выбрать, когда их использовать?
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
и это использовать.