Conditionally implementing __iter__ in new style classes

Bengt Richter bokr at oz.net
Fri Jul 8 02:16:19 EDT 2005


On Thu, 07 Jul 2005 22:04:31 +0200, Thomas Heller <theller at python.net> wrote:

>bokr at oz.net (Bengt Richter) writes:
>
>> 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
>
>Of course.  I didn't spot this, but I cannot use this anyway for 2.3
>compatibility.
>
>>  ...
>>  >>> 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'
>
>I don't understand what you mean here.  A __iter__ instance attribute?
>
Yes, but it seems very unlikely to cause a problem, especially since iter(inst)
bypasses it, as you probably would want. In other words, never mind ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list