Conditionally implementing __iter__ in new style classes
Thomas Heller
theller at python.net
Thu Jul 7 16:04:31 EDT 2005
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?
Thomas
More information about the Python-list
mailing list