Ethan Furman added the comment:
Your example shows /having/ an iterator, while mine is /being/ an iterator.
A simple iterator:
# iterator protocol
class uc_iter():
def __init__(self, text):
self.text = text
self.index = 0
def __iter__(self):
return self
def __next__(self):
try:
result = self.text[self.index].upper()
except IndexError:
raise StopIteration
self.index += 1
return result
ucii = uc_iter('abc')
I believe your over-arching goal is a proxy class?
class GenericProxy:
def __init__(self, proxied):
self.proxied = proxied
# in case proxied is an __iter__ iterator
@property
def __iter__(self):
if not hasattr(self.proxied, '__iter__'):
raise AttributeError
else:
return self
@property
def __next__(self):
if not hasattr(self.proxied, '__next__'):
raise AttributeError
else:
return next(self.proxied)
and then two proxies to test -- a non-iterable and an iterable:
gp_ni = GenericProxy(object())
gp_ucii = GenericProxy(ucii)
and a quick harness:
try:
for _ in iter(gp_ni):
print(_)
except Exception as e:
print(e)
try:
for _ in iter(gp_ucii):
print(_)
except Exception as e:
print(e)
Note: the presence/absence of iter() makes no difference to the results below.
The non-iterable gives the correct error: 'GenericProxy' object is not iterable
But the iterable gives: 'GenericProxy' object is not callable
That error message is a result of the iter machinery grabbing the __next__
attribute and trying to call it, but property attributes are not callable.
In other words, iter() does not "honor the descriptor protocol".
So now we have two: callable() and iter(). How many more are there?
----------
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue23990>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com