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