Conditionally implementing __iter__ in new style classes

Bengt Richter bokr at oz.net
Thu Jul 7 12:21:06 EDT 2005


On Thu, 07 Jul 2005 09:51:42 +0200, Thomas Heller <theller at python.net> wrote:

>bokr at oz.net (Bengt Richter) writes:
>
>> On Wed, 06 Jul 2005 17:57:42 +0200, Thomas Heller <theller at python.net> wrote:
>>
>>>I'm trying to implement __iter__ on an abstract base class while I don't
>>>know whether subclasses support that or not.
>
>> Will a property or custom descriptor do what you want? E.g.
>>
>>  >>> class Base(object):
>>  ...     def __getIter(self):
>>  ...         if hasattr(self, "Iterator"):
>>  ...             return self.Iterator
>>  ...         raise AttributeError, name
>>  ...     __iter__ = property(__getIter)
[...]
>
>Yep, that's exactly what I need - thanks.
>
BTW, I forgot to mention that you could use property as a decorator
in the above single-argument case:

 >>> class Base(object):
 ...     @property
 ...     def __iter__(self):
 ...         if hasattr(self, "Iterator"):
 ...             return self.Iterator
 ...         raise AttributeError, name
 ...
 >>> class Concrete(Base):
 ...     def Iterator(self):
 ...         yield 1
 ...         yield 2
 ...         yield 3
 ...
 >>> iter(Base())
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: iteration over non-sequence
 >>> iter(Concrete())
 <generator object at 0x02EF152C>
 >>> list(iter(Concrete()))
 [1, 2, 3]

Hope there isn't a gotcha for your use case in the way an instance attribute
of the same name is allowed. A custom descriptor could eliminate that.

 >>> inst = Concrete()
 >>> list(iter(inst))
 [1, 2, 3]
 >>> inst.__init__ = 'abc'
 >>> list(iter(inst))
 [1, 2, 3]
 >>> inst.__init__
 'abc'



Regards,
Bengt Richter



More information about the Python-list mailing list