Читаем Автостопом по 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 удаляется лишь при нормальном завершении работы).

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

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

100 знаменитых харьковчан
100 знаменитых харьковчан

Дмитрий Багалей и Александр Ахиезер, Николай Барабашов и Василий Каразин, Клавдия Шульженко и Ирина Бугримова, Людмила Гурченко и Любовь Малая, Владимир Крайнев и Антон Макаренко… Что объединяет этих людей — столь разных по роду деятельности, живущих в разные годы и в разных городах? Один факт — они так или иначе связаны с Харьковом.Выстраивать героев этой книги по принципу «кто знаменитее» — просто абсурдно. Главное — они любили и любят свой город и прославили его своими делами. Надеемся, что эти сто биографий помогут читателю почувствовать ритм жизни этого города, узнать больше о его истории, просто понять его. Тем более что в книгу вошли и очерки о харьковчанах, имена которых сейчас на слуху у всех горожан, — об Арсене Авакове, Владимире Шумилкине, Александре Фельдмане. Эти люди создают сегодняшнюю историю Харькова.Как знать, возможно, прочитав эту книгу, кто-то испытает чувство гордости за своих знаменитых земляков и посмотрит на Харьков другими глазами.

Владислав Леонидович Карнацевич

Неотсортированное / Энциклопедии / Словари и Энциклопедии