Справочная информация
Резюме альтернативных контейнеров данных, основанных на атрибутах, было представлено Р. Хеттингером на встрече праздника SF Python 2017 года.Смотрите его твит и его слайд-колоду .Он также дал доклад на PyCon 2018 по классам данных.
Другие типы контейнеров данных упоминаются в этой статье и преимущественно в документации по Python 3 (см. Ссылки ниже).
Здесь обсуждается список рассылки python-ideas о добавлении recordclass
в стандартную библиотеку.
Опции
Альтернативы в стандартной библиотеке
Внешние опции
- records : изменяемый именованный кортеж (см. Также recordclass )
- Связки : добавить атрибут доступа к диктовкам (вдохновение для
SimpleNamedspace
) - box : обтекание диктов с поиском в точечном стиле функциональность
- attrdict : доступ к элементам из сопоставления в виде ключей или атрибутов
- поля : удалить шаблон из классов контейнеров.
- namedlist : изменяемые контейнеры, похожие на кортежи, по умолчанию E. Smith
Какой?
Решение о том, какой вариант использовать, зависит от ситуации (см. Примеры ниже).Обычно достаточно старомодный изменяемый словарь или неизменный именованный набор.Классы данных являются новейшим дополнением (Python 3.7a), предлагающим как изменчивость, так и необязательную неизменяемость , с обещанием уменьшения стандартного шаблона, вдохновленного проектом attrs .
Примеры
import typing as typ
import collections as ct
import dataclasses as dc
# Problem: You want a simple container to hold personal data.
# Solution: Try a NamedTuple.
>>> class Person(typ.NamedTuple):
... name: str
... age: int
>>> a = Person("bob", 30)
>>> a
Person(name='bob', age=30)
# Problem: You need to change age each year, but namedtuples are immutable.
# Solution: Use assignable attributes of a traditional class.
>>> class Person:
... def __init__(self, name, age):
... self.name = name
... self.age = age
>>> b = Person("bob", 30)
>>> b.age = 31
>>> b
<__main__.Person at 0x4e27128>
# Problem: You lost the pretty repr and want to add comparison features.
# Solution: Use included repr and eq features from the new dataclasses.
>>> @dc.dataclass(eq=True)
... class Person:
... name: str
... age: int
>>> c = Person("bob", 30)
>>> c.age = 31
>>> c
Person(name='bob', age=31)
>>> d = Person("dan", 31)
>>> c != d
True