2

Example

Take the following example

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 

In Leaf.__get__ instance points to the Branch instance. However, I need to access value, which is an instance member of Root.

Background

My task is to write a parser for a large file header. The parser shall be robust and fast. Therefore, instead of parsing the whole header structure, I proposed to use descriptors to lazy parse the fields. This allows for decoding/encoding the header fields only when required. So, there's a root object that holds the complete header as a bytearray and when a field is accessed, its descriptor reads from or writes to this bytearray. However, the header structure is hierarchical and contains nested fields. For that reason I need to access the roots bytearray from a nested descriptor.

Related questions and solutions

Similar questions about instance descriptors have been raised before.

1. Create a per instance

The solution would be to add the descriptors to the instances instead of classes and set the shared value as reference. IMO this seems a bit inefficient.

See Dynamically adding @property in python and Python - How to pass instance variable value to descriptor parameter?

2. Override __getattribute__

I don't think this would work, since __getattribute__ of Branch doesn't know about the Root instance.

3. Propagate value

While traversing the structure, Branch.__get__ gets called, where we could store a reference to the root instance, which is accessible from Leaf.__get__. However, this will not work if we mix up calls on multiple instances of Root.


Finally, my question is if there are better solutions for this specific problem?

3
  • Do you need Branch and Leaf instances to be class variables in Root and Branch classes respectively? Commented Feb 7, 2018 at 22:57
  • Listed as the first solution in Related questions it might be a solution to use instance descriptors instead of class descriptors. However, I think this would increase the memory footprint a lot, since for every instance of Root a bunch of Branches and Leafs need to be duplicated. Commented Feb 7, 2018 at 23:03
  • I don't think you can do it given the constraints without involving some traceback magic to get the root instance from parent frames. I would suggest not using nested descriptors if memory is such a big concern, but implementing the logic in Branch (you can use __getattr__ for evaluating missing values). Commented Feb 7, 2018 at 23:24

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.