Conditionally implementing __iter__ in new style classes
Thomas Heller
theller at python.net
Wed Jul 6 12:07:10 EDT 2005
Thomas Heller <theller at python.net> writes:
> I'm trying to implement __iter__ on an abstract base class while I don't
> know whether subclasses support that or not.
> Hope that makes sense, if not, this code should be clearer:
>
> class Base:
> def __getattr__(self, name):
> if name == "__iter__" and hasattr(self, "Iterator"):
> return self.Iterator
> raise AttributeError, name
>
> class Concrete(Base):
> def Iterator(self):
> yield 1
> yield 2
> yield 3
>
> The idea is that if a subclass of Base defines an 'Iterator' method,
> instances are iterable. They are not iterable otherwise.
>
> The above gives the expected behaviour: iter(Base()) raises a
> "TypeError: iteration over non-sequence", and iter(Concrete()) returns a
> generator.
>
> If, however, I make Base a newstyle class, this will not work any
> longer. __getattr__ is never called for "__iter__" (neither is
> __getattribute__, btw). Probably this has to do with data descriptors
> and non-data descriptors, but I'm too tired at the moment to think
> further about this.
>
> Is there any way I could make the above code work with new style
> classes?
I forgot to mention this: The Base class also implements a __getitem__
method which should be used for iteration if the .Iterator method in the
subclass is not available. So it seems impossible to raise an exception
in the __iter__ method if .Iterator is not found - __iter__ MUST return
an iterator if present.
Thomas
More information about the Python-list
mailing list