Python attribute with simultaneous __get__ and __getitem__ behavior

Viewed 133

EDIT:

I updated the original title Python descriptor behavior with _getitem_ method because, as pointed out in the comments, what I am after seems not to be possible using descriptors. But maybe there are other ways to achieve this?


I have an object that employs lazy loading of a very large numpy array. It is implemented in such a way that calling object[idx] only loads the value corresponding to the index, while object[:] produces the full array.

What I would like to do is to use this object as a property-like attribute in another class that omits the need of [:] when calling the full array while still maintaining the lazy loading aspect if an index or slice is provided. I can achieve the first when defining a descriptor with an appropriate __get__ method:

class MyDescriptor:
    
    def __get__(self, instance, owner=None):
        return instance._lazy_array[:]


class Foo:

    lazy_array = MyDescriptor()
    
    def __init__(self, lazy_array_obj):
        self._lazy_array = lazy_array_obj

foo = Foo(lazy_array_obj)

Calling foo.lazy_array now produces the full array. However, calling foo.lazy_array[0] loads the full array and only indexes it afterwards, losing the performance gain from loading only a part of the data.

In theory, what I would need is a __getitem__ method that supports the descriptor protocol, but that does not seem to exist. Is there any other solution that I am missing here?

Additional detail: The lazy array object is a tdms channel produced by the lazy loading of a tdms file using nptdms

0 Answers
Related