Читаем Автостопом по Python полностью

Это примеры применения модулей как пространств имен (в конце концов, они же являются отличной штукой) для разделения функций вместо того, чтобы использовать ненужные классы. Мы узнаем предназначение каждой функции по ее имени, например formats._csv.import_set(), formats._tsv.import_set() и formats._json.import_set() импортируют наборы данных из файлов в формате CSV, TSV и JSON соответственно. Другие функции отвечают за экспорт данных и определение формата файла (где это возможно) для каждого доступного Tablib формата.


Дескрипторы и декораторы свойств (используйте неизменяемость, когда это идет на пользу API)

Tablib — наша первая библиотека, в которой используется синтаксис декораторов Python, описанный в подразделе «Декораторы» раздела «Структурируем проект» главы 4. Синтаксисом предусмотрено указывать символ @ перед именем функции, вся конструкция размещается над другой функцией. Декоратор изменяет (или декорирует) функцию, которая находится под ним. В следующем фрагменте кода свойство изменяет функции Dataset.height и Dataset.width, делая их дескрипторами — классами, в которых определен хотя бы один из следующих методов: _get_(), __set__() или __delete__() (геттер, сеттер и метод удаления). Например, поиск атрибута Dataset.height приведет к срабатыванию функции-геттера, сеттера или удаления в зависимости от контекста применения атрибута. Такое поведение присуще только новым классам (их мы вскоре обсудим). Для получения более подробной информации о дескрипторах обратитесь к довольно полезному руководству по Python по адресу https://docs.python.org/3/howto/descriptor.html.

Именно так используется декоратор. В данном случае свойство изменяет Dataset.height, чтобы оно вело себя как свойство, а не как связанный метод. Он может работать только с методами классов.

Когда свойство применяется как декоратор, атрибут height вернет высоту Dataset, но вы не можете задать высоту множества данных, вызвав Dataset.height.

Так выглядят атрибуты height и width при использовании:

>>> import tablib

>>> data = tablib.Dataset()

>>> data.header = ("amount", "ingredient")

>>> data.append(("2 cubes", "Arcturan Mega-gin"))

>>> data.width

2

>>> data.height

1

>>>

>>> data.height = 3

Traceback (most recent call last):

File "", line 1, in

AttributeError: can't set attribute

Доступ к data.height можно получить так же, как и к любому другому атрибуту, но изменить его значение вы не можете — оно высчитывается на основе данных и всегда актуально. Такой дизайн API весьма эргономичен: конструкцию data.height проще ввести на клавиатуре, чем data.get_height(); понятно, что означает data.height. Поскольку значение этого свойства выводится на основе данных (значение свойства нельзя задать, для него определена только функция-геттер), можно не переживать, что значение свойства рассинхронизируется с реальными данными.

Декоратор свойства можно применить только к атрибутам классов и только к тем классам, которые наследуют от base object object (например, class MyClass(object), а не class MyClass() — в Python 3 всегда выполняется наследование от объекта).

Один и тот же инструмент используется при создании API для импорта и экспорта данных в Tablib для разных форматов (Tablib не хранит строку для каждого формата). Вместо этого применяются Dataset-атрибуты csv, json и yaml, они похожи на свойства Dataset.height и Dataset.width, показанные в предыдущем примере: вызывают функцию, которая генерирует результат из сохраненных данных или преобразует входной формат и затем заменяет основные данные. Но существует только один набор данных.

Когда свойство data.csv находится с левой стороны знака «равно», вызывается функция-сеттер для этого свойства, которая преобразует dataset из формата CSV. Когда свойство data.yaml находится с правой стороны знака «равно» или стоит отдельно, вызывается функция-геттер для создания строки в заданном формате на основе внутреннего набора данных. Рассмотрим пример.

Свойство data.csv, которое стоит с левой стороны от знака «равно» (оператора присваивания), вызывает функцию formats.csv.import_set(), передавая data в качестве первого аргумента, и строку, содержащую ингредиенты Пангалактического Грызлодера, в качестве второго аргумента.

Свойство data.yaml, стоящее отдельно, вызывает функцию formats.yaml.export_set(), передавая data в качестве аргумента, выводя строку в формате YAML для функции print().

Функции для получения, установки и удаления данных могут быть привязаны к единому атрибуту с помощью property. Его сигнатура выглядит так: property(fget=None, fset=None, fdel=None, doc=None), fget определяет функцию-геттер (formats.csv.im­port_set()), fset — функцию-сеттер (for­mats.csv.export_set()), а fdel — функцию удаления данных (оставлена пустой). Далее мы увидим код, в котором программно устанавливаются свойства форматирования.


Перейти на страницу:

Похожие книги

Из жизни попаданцев
Из жизни попаданцев

Уважаемые читатели! Этот фанфик не пропагандирует идеи национал-социализма и идеалы СС. Автор считает, что лучше всего в непривычный мир может вписаться разведчик или диверсант. Учитывая начало фика, лучшим кандидатом на роль главного героя оказался немец. Автор много читал про диверсантов времен ВМВ. Образ главного героя собирательный, автор использовал факты биографии некоторых друзей и подчиненных Отто Скорцени. Если по каким-либо причинам такой главный герой является для вас неприемлемым, то, убедительная просьба, ПРОСТО НЕ ЧИТАЙТЕ.Ну, а для тех, кто всё-таки решился... В 1945 году Дамблдор и Гриндевальд проводили некий ритуал. Ритуал сорвал офицер СС… «Внизу у лестницы обнаружился еще один труп. Его унесли вместе с трупом красноглазого. Насколько я понял, это был хозяин дома и муж Лили, а также отец маленького Гарри, некий Джеймс Поттер. Честно говоря, я даже обрадовался этому обстоятельству. Во-первых, муж точно заметил бы, что с женой что-то не так, а во-вторых, только мужа мне и не хватало. В-третьих, в гостиной обнаружилась газета со странными движущимися картинками. А на газете была дата… 31 октября 1981 года…»Да-да, мать маленького Гарри осталась жива. Чудом уцелела. Вот, только...

Алексей Бухтояров , Заязочка , Заязочка

Неотсортированное / Фанфик / Попаданцы