Python: вставьте атрибут в объект, созданный библиотекой C - PullRequest
1 голос
/ 24 февраля 2011

Я пытаюсь вставить атрибут в lxml.etree._Element, но, поскольку этот модуль полностью реализован на C, setattr завершается неудачно:

Traceback (most recent call last):
[...]
    setattr(node.getroottree().getroot(), "attributeName", value)
AttributeError: 'lxml.etree._Element' object has no attribute 'attributeName'

Вариант использования: у меня есть функция, которая извлекаетТекст из XML-файла XPath и заменяет $(ENV) -подобные совпадения на соответствующее значение.Поэтому я не хочу передавать словарь переменных (например, {"ENV" : "replacement"} этой функции каждый раз. Вместо этого было бы проще просто иметь атрибут в фиксированном месте (корень XML в моем коде). Я мог бы сделатьтупой обходной путь, но внедрение атрибута Python было бы лучшим способом. Я не могу использовать глобальную переменную, потому что каждый XML-файл может иметь разные значения переменных.

Итак, есть ли способ внедрить что-то в классы / объекты на основе C?

1 Ответ

0 голосов
/ 24 февраля 2011

Вы обычно не можете, поскольку экземпляры определенных C-типов обычно не имеют для каждого экземпляра __dict__ записей для хранения произвольных атрибутов.

Обходной путь для случаев, когда подкласс или класс-обертка не будут работать, - это создание вспомогательного словаря на уровне модуля, который сопоставляет имеющийся у вас объект с дополнительной информацией. Если объект, который у вас есть, не является хэшируемым, вы можете использовать id(obj).

Так, например, вы можете сохранить словарь, связанный с идентификатором каждого корневого объекта:

# Module level, setting up the data store
from collections import defaultdict
extra_info = defaultdict(dict) # Creates empty dicts for unknown keys

# Saving the info
root = node.getroottree().getroot()
extra_info[id(root)]["ENV"] = "replacement"

# Retrieving it later
root = node.getroottree().getroot()
info = extra_info[id(root)]
...