Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to override Python list(iterator) behaviour?

Tags:

python

Running this:

class DontList(object):
    def __getitem__(self, key):
        print 'Getting item %s' % key
        if key == 10: raise KeyError("You get the idea.")
        return None

    def __getattr__(self, name):
        print 'Getting attr %s' % name
        return None

list(DontList())

Produces this:

Getting attr __length_hint__
Getting item 0
Getting item 1
Getting item 2
Getting item 3
Getting item 4
Getting item 5
Getting item 6
Getting item 7
Getting item 8
Getting item 9
Getting item 10
Traceback (most recent call last):
  File "list.py", line 11, in <module>
    list(DontList())
  File "list.py", line 4, in __getitem__
    if key == 10: raise KeyError("You get the idea.")
KeyError: 'You get the idea.'

How can I change that so that I'll get [], while still allowing access to those keys [1] etc.?

(I've tried putting in def __length_hint__(self): return 0, but it doesn't help.)

My real use case: (for perusal if it'll be useful; feel free to ignore past this point)

After applying a certain patch to iniparse, I've found a nasty side-effect to my patch. Having __getattr__ set on my Undefined class, which returns a new Undefined object. Unfortunately, this means that list(iniconfig.invalid_section) (where isinstance(iniconfig, iniparse.INIConfig)) is doing this (put in simple prints in the __getattr__ and __getitem__):

Getting attr __length_hint__
Getting item 0
Getting item 1
Getting item 2
Getting item 3
Getting item 4

Et cetera ad infinitum.

like image 679
Chris Morgan Avatar asked Nov 23 '10 13:11

Chris Morgan


1 Answers

If you want to override the iteration then just define the __iter__ method in your class

like image 111
Jakob Bowyer Avatar answered Sep 20 '22 01:09

Jakob Bowyer