#python #class #coding-style #metadata
#python #класс #стиль кодирования #метаданные
Вопрос:
Я работаю над структурой структурированного анализа данных, которая основана на потоковой передаче данных между узлами. В настоящее время узлы реализованы как подклассы класса корневого узла, предоставляемого фреймворком. Для каждого класса / фабрики узлов мне нужны метаданные, такие как список атрибутов узла, их описание, выходные данные узла. Метаданные могут быть обоими: для конечных пользователей во интерфейсном приложении или для использования в программировании — некоторые другие инструменты управления потоками. В будущем их будет больше.
(Обратите внимание, что я только начал изучать python во время написания этого кода)
В настоящее время метаданные предоставляются в переменной класса
class AggregateNode(base.Node):
"""Aggregate"""
__node_info__ = {
"label" : "Aggregate Node",
"description" : "Aggregate values grouping by key fields.",
"output" : "Key fields followed by aggregations for each aggregated field. Last field is "
"record count.",
"attributes" : [
{
"name": "keys",
"description": "List of fields according to which records are grouped"
},
{
"name": "record_count_field",
"description": "Name of a field where record count will be stored. "
"Default is `record_count`"
}
]
}
Другие примеры можно найти здесь .
Я чувствую, что это можно сделать гораздо более чистым способом. Существует одно ограничение: поскольку узлы являются пользовательскими классами подклассов, должно быть минимальное вмешательство в потенциальные будущие имена атрибутов.
То, что я думал сделать, это разделить текущий node_info. Он должен был быть закрытым для фреймворка, но теперь я понимаю, что он имеет гораздо более широкое применение. Я думал об использовании атрибутов node_: будет иметь общее пространство имен атрибутов, не принимая слишком много имен из потенциальных пользовательских атрибутов узла.
Мой вопрос: каков наиболее распространенный способ предоставления таких метаданных в программах на Python? Одна переменная со словарем? Несколько переменных, по одной для каждого атрибута метаданных? (это противоречило бы ограничению) Пользовательский класс / структура? Использовать какой-то префикс, например, node_ * и использовать несколько переменных?
Комментарии:
1. Просто чтобы добавить еще один пример использования метаданных: потоковая сеть будет настраиваться через словарь с кортежами node attribute value, а функция настройки должна заботиться о значениях по умолчанию и предотвращать установку защищенных атрибутов при определенных обстоятельствах (например, некоторые атрибуты будут устанавливаться только в коде, другие будут открыты дляпользовательский интерфейс).
2. Не создавайте пользовательские имена, которые начинаются и заканчиваются двойным подчеркиванием. У меня сейчас нет ссылки, но они считаются зарезервированными, так что любое их использование явно относится к языковой функции, а не к определяемой пользователем переменной.
Ответ №1:
Я не уверен, существует ли какой-то «стандартный» способ хранения пользовательских метаданных в объектах python, но в качестве примера реализация dbus на python добавляет атрибуты с префиксом « _dbus
« к опубликованным методам и сигналам.
Комментарии:
1. Используется обычный, общедоступный
node_info
.
Ответ №2:
Многие функции, которые вы описываете, перекрываются с epydoc:
>>> class AggregateNode(base.Node):
... r"""
... Aggregate values grouping by key fields.
...
... @ivar keys: List of fields according to which records are grouped
...
... @ivar record_count_field: Name of a field where record count will be
... stored.
... """
... record_count_field = "record_count"
...
... def get_output(self):
... r"""
... @return: Key fields followed by aggregations for each aggregated field.
... Last field is record count.
... """
...
>>> import epydoc.docbuilder
>>> api = epydoc.docbuilder.build_doc(AggregateNode)
>>> api.variables['keys'].descr.to_plaintext(None)
u'List of fields according to which records are groupednn'
>>> api.variables['record_count_field'].value.pyval
'record_count'
Комментарии:
1. Спасибо, полезно знать, так как это может быть полезно для некоторых других проектов. Однако мне это нужно не только для целей документации. Он будет использоваться, например, при создании формы пользовательского интерфейса и автоматической (защищенной) конфигурации узла. Мне нужно больше информации для @ivar, чем его описание.
2. Вы также можете использовать epydoc для указания его типа и значения по умолчанию. В вашем примере приведено только описание; что еще вам нужно?
3. Я сожалею о недостаточном примере. Помимо значений по умолчанию и типа, будет: область защиты или тип проверки / вызываемый (в настоящее время реализующий материал, который его использует). В будущем их наверняка будет больше.
4. Вы также можете упомянуть такие вещи, как предварительное условие или постусловие, для большинства вызываемых объектов; epydoc не придает этому никакого значения; но вы, вероятно, могли бы указать это в терминах выражения, которое должно быть истинным, чтобы удовлетворить условию; или как объект python, который каким-то образом представляет условие.
Ответ №3:
Единственным элементом класса Python, способным изменять само определение класса (следовательно, метаданные), является __new__()
функция, new вызывается до фактического создания объекта и до инициализации. Вы можете использовать его для чтения / изменения внутренней структуры ваших классов / узлов до их инициализации с помощью __init__()