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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.