Message241423
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? |
|
Date |
User |
Action |
Args |
2015-04-18 16:23:18 | ethan.furman | set | recipients:
+ ethan.furman, terry.reedy, belopolsky, christian.heimes, ionelmc, Claudiu.Popa, llllllllll, jedwards |
2015-04-18 16:23:18 | ethan.furman | set | messageid: <1429374198.17.0.775176925984.issue23990@psf.upfronthosting.co.za> |
2015-04-18 16:23:18 | ethan.furman | link | issue23990 messages |
2015-04-18 16:23:17 | ethan.furman | create | |
|