Обычно вам не следует об этом беспокоиться: обратите внимание, что свойство __slots__ не появляется в классах Dataset или Databook — только в классе Row, но поскольку рядов данных может быть очень много, использование __slots__ выглядит хорошим решением. Класс Row не показан в tablib/__init__.py, поскольку является вспомогательным классом для класса Dataset, для каждой строки создается один объект такого класса.
Рассмотрим, как выглядит определение __slots__ в самом начале определения класса Row:
class Row(object):
····"""Внутренний объект Row. Используется в основном для фильтрации."""
····__slots__ = ['_row', 'tags']
····def __init__(self, row=list(), tags=list()):
········self._row = list(row)
········self.tags = list(tags)
····#
····#… и т. д…
····#
Проблема в том, что больше не существует атрибута __dict__, в котором хранятся объекты класса Row, но функция pickle.dump() (вызывается для сериализации объектов) по умолчанию использует __dict__ для сериализации объектов, если только не определен метод __getstate__(). Аналогично во время десериализации (процесса, который читает сериализованные байты и восстанавливает объект в памяти), если метод __setstate__() не определен, метод pickle.load() загружает данные в атрибут объекта __dict__. Рассмотрим, как это обойти.
class Row(object):
····#
····#… пропускаем другие определения…
····#
····def __getstate__(self):
········slots = dict()
········for slot in self.__slots__:
············attribute = getattr(self, slot)
············slots[slot] = attribute
········return slots
····def __setstate__(self, state):
········for (k, v) in list(state.items()):
············setattr(self, k, v)
Для получения более подробной информации о методах __getstate__() и __setstate__() и сериализации обратитесь к документации __getstate__ (http://bit.ly/__getstate__-doc).
Примеры из стиля Tablib
Мы подготовили лишь один пример использования стиля в Tablib — перегрузка операторов (это позволяет рассмотреть детали модели данных Python). Настройка поведения ваших классов позволит разработчикам, использующим ваш API, писать хороший код.
Перегрузка операторов (красивое лучше, чем уродливое). В этом фрагменте кода приводится перегрузка операторов Python, чтобы выполнять операции для строк или столбцов набора данных. В первом фрагменте кода показывается интерактивное применение квадратных скобок [] как для численных индексов, так и для имен столбцов, а во втором — код, который использует это поведение.
В части кода класса Dataset, которая определяет поведение оператора «квадратные скобки», показывается, как обрабатывать доступ по имени столбца и номеру строки.