Python: как получить доступ к атрибутам экземпляра во вложенных дескрипторах?
пример
Возьмите следующий пример
class Leaf:
def __get__(self, instance, owner):
if instance is None:
return self
# TODO How to access Root.value here?
class Branch:
bar = Leaf()
class Root:
foo = Branch()
def __init__(self, value):
self.value = value
if __name__ == '__main__':
x = Root(20)
y = Root(30)
print(x.foo.bar) # 20
a = x.foo
print(a.bar) # 20
print(y.foo.bar) # 30
print(a.bar) # 20
В Leaf.__get__
instance
указывает на Branch
пример. Тем не менее, мне нужно получить доступ value
, который является экземпляром члена Root
,
Фон
Моя задача - написать парсер для большого заголовка файла. Парсер должен быть надежным и быстрым. Поэтому вместо синтаксического анализа всей структуры заголовка я предложил использовать дескрипторы для ленивого разбора полей. Это позволяет декодировать / кодировать поля заголовка только при необходимости. Итак, есть корневой объект, который содержит полный заголовок в виде байтового массива, и при обращении к полю его дескриптор выполняет чтение или запись в этот байтовый массив. Однако структура заголовка является иерархической и содержит вложенные поля. По этой причине мне нужно получить доступ к корневому массиву байтов из вложенного дескриптора.
Похожие вопросы и решения
Подобные вопросы об дескрипторах экземпляра были подняты ранее.
1. Создать экземпляр
Решением было бы добавить дескрипторы к экземплярам вместо классов и установить общее значение в качестве ссылки. ИМО это кажется немного неэффективным.
См. Динамическое добавление @property в Python и Python - Как передать значение переменной экземпляра в параметр дескриптора?
2. Переопределить__getattribute__
Я не думаю, что это будет работать, так как __getattribute__
из Branch
не знает о Root
пример.
3. Распространятьvalue
Пересекая структуру, Branch.__get__
вызывается, где мы можем хранить ссылку на корневой экземпляр, который доступен из Leaf.__get__
, Тем не менее, это не будет работать, если мы смешаем вызовы на нескольких экземплярах Root
,
Наконец, мой вопрос: есть ли лучшие решения для этой конкретной проблемы?