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

Простой пользовательский интерфейс. Для того чтобы создать собственный сборщик данных, пользователь должен создать подкласс абстрактного класса Collector, а затем предоставить путь к нему с помощью конфигурационного файла. Рассмотрим пример нового определения класса Collector из класса Diamond/src/collectors/cpu/cpu.py. Когда Python ищет метод collect(), он сначала проверит на наличие CPUCollector, а затем, если оно не будет найдено, использует метод diamond.col­lector.Collector.collect(), что сгенерирует исключение NotImplementedError.

Код сборщика может выглядеть так:

# coding=utf-8

import diamond.collector

import psutil

class CPUCollector(diamond.collector.Collector):

def collect(self):

# В классе Collector содержится лишь инструкция raise(NotImplementedError)

metric_name = "cpu.percent"

metric_value = psutil.cpu_percent()

self.publish(metric_name, metric_value)

Стандартное место для размещения определений сборщиков — каталог venv/share/diamond/collectors/, но вы можете хранить их по тому адресу, который укажете в свойстве collectors_path конфигурационного файла. Имя класса CPUCollector уже указано в примере конфигурационного файла. За исключением добавления спецификаций hostname или hostname_method в общие стандартные свойства (расположенные под конфигурационным файлом) или в отдельные переопределенные значения для сборщика, как показано в следующем примере, не нужно вносить другие изменения (в документации перечислены дополнительные настройки сборщиков (http://bit.ly/optional-collector-settings)): [[CPUCollector]]

enabled = True

hostname_method = smart

Более сложен внутренний код. За кулисами сервер вызовет метод utils.load_collectors(), используя путь, указанный в collectors_path. Рассмотрим большую часть этой функции (мы сократили ее для удобства).

Разбиваем строку (первый вызов функции); в противном случае пути являются списками строк, содержащих пути, которые указывают места, где реализованы пользовательские подклассы класса Collector.

Здесь мы рекурсивно проходим по заданным путям, добавляя каждую папку в sys.path, чтобы далее можно было импортировать подклассы класса Collector.

Здесь выполняется рекурсия — метод load_collectors() вызывает сам себя60.

После загрузки сборщиков из подкаталогов обновите оригинальный словарь пользовательских сборщиков, добавив туда загруженные сборщики из этих подкаталогов.

С момента введения Python 3.1 модуль importlib стандартной библиотеки Python является предпочтительным способом сделать это (с помощью модуля importlib.import_module; фрагменты importlib.import_module также были портированы в Python 2.7). Это показывает, как можно программно импортировать модуль, используя строку с его именем.

Так можно программно получить доступ к атрибутам модуля, имея лишь строку с именем атрибута.

Метод load_dynamic_class здесь можно и не использовать. Он повторно импортирует модуль, проверяет, что названный класс является классом на самом деле, проверяет, что он является подклассом класса Collector, и, если это верно, — возвращает только что загруженный класс. Избыточность часто встречается в исходном коде, который пишут большие группы людей.

Здесь они получают имя класса для дальнейшего использования при применении настроек из файла конфигурации (имея только строку, содержащую имя класса).


Примеры из стиля Diamond

В Diamond вы можете найти отличный пример использования замыкания, который демонстрирует все, о чем мы говорили в пункте «Замыкания с поздним связыванием» подраздела «Распространенные подводные камни» раздела «Стиль кода» главы 4 по поводу того, что такое поведение зачастую весьма желательно.

Пример использования замыкания (когда подводный камень вовсе не подвод­ный камень).Замыкание — это функция, использующая переменные, доступные в локальной области видимости, которые в противном случае будут недоступны при вызове функции. В других языках их, возможно, будет трудно реализовать и понять, но это не относится к Python, поскольку в нем функции обрабатываются так же, как и любые другие объекты61. Например, функции могут быть переданы как аргумент, также их можно возвращать из других функций.

Рассмотрим фрагмент кода исполняемого файла diamond, который показывает, как реализовать замыкание в Python.

Когда мы пропускаем код, отсутствующие части описываем в комментарии, перед которым стоят две тильды (##~~).

Мы пользуемся файлом PID62, чтобы убедиться, что демон уникален (то есть мы не запустили его дважды случайно), а также для быстрого сообщения с другими сценария­ми при передаче им связанных идентификаторов процессов. Этот файл также нужен для того, чтобы удостовериться, что процесс завершился ненормально (поскольку в этом сценарии файл PID удаляется лишь при нормальном завершении работы).

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

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

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

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

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

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