tags:

views:

758

answers:

3
+5  Q: 

Python lazy list

I would like create my own collection that has all the attributes of python list and also knows how to saved/loaded itself database. Also I want to make the load implicit and lazy, as in it shouldn't get called at the point of creation of the list but at it's first usage.

Is there a single __ xxx __ method I can override to load the list on first usage of any list property( such as len, getitem, iter..) without having to override them all?

+3  A: 

__getattribute__

fivebells
And that's all I have to say about that... :)
Kevin Little
That doesn't actually work. http://codepad.org/Lwcgbj7Z
Glyph
@Glyph that code you pasted would work if you defined __getitem__
Dan
+3  A: 

No, there isn't.

hop
+4  A: 

Not exactly. For emulating things other than lists, there's __getattribute__, but unfortunately Python doesn't consider operators like x[y] or x(y) to be exactly the same as x.__getitem__(y) or x.__call__(y). Operators like that are attributes of the class, not attributes of the instance, as you can see here.

However, you can take advantage of Python's dynamic nature to effectively eliminate that distinction. If your main concern is to save yourself typing, and to produce less code that needs maintaining, you can do something like this:

class override(object):
    def __init__(self, methodName):
        self.methodName = methodName

    def __get__(self, oself, cls):
        oself._load(self.methodName)
        return getattr(super(oself.__class__, oself), self.methodName)

class LazyList(list):
    def _load(self, name):
        print 'Loading data for %s...' % (name,)

    for methodName in set(dir(list)) - set(dir(object)):
        locals()[methodName] = override(methodName)

You probably don't want to use dir() in real life, but a suitable fixed list of strings could work as a substitute.

Glyph
In the _load function, you should call list.<function>(self,..) to add data to prevent recursive loading. Example: list.append(self, value)
Staale