Y
Yves
Hi!
I was fiddling around a bit with iterators and I came across some
strange behaviour. I have the following simple code:
--
class A(object):
def __init__(self, n):
self.n = n
def __iter__(self):
return self
def next(self):
if self.n > 0:
self.n -= 1
return "A: %d" % self.n
else:
raise StopIteration()
class B(A):
def __init__(self, n):
super(B,self).__init__(n)
def __iter__(self):
return self
def next(self):
if self.n > 0:
self.n -= 1
return "B: %d" % self.n
else:
raise StopIteration()
class C(A):
def __init__(self, n):
super(C,self).__init__(n)
self.next = self.mynext
def __iter__(self):
return self
def mynext(self):
if self.n > 0:
self.n -= 1
return "C: %d" % self.n
else:
raise StopIteration()
if __name__=='__main__':
a = A(2)
b = B(2)
c = C(2)
for k in [a,b,c]:
# Iterate over the object
for i in k:
print i
print "="*50
--
The output I expected was
A: 1
A: 0
==================================================
B: 1
B: 0
==================================================
C: 1
C: 0
==================================================
but strangely enough I ended up with
A: 1
A: 0
==================================================
B: 1
B: 0
==================================================
A: 1
A: 0
==================================================
Or in other words, it appears that Python does not use 'mynext' when
iterating over an object of class C. When I call c.next() directly
though, it does execute the code from the 'mynext' method. In my
understanding, iterating over a list, simply consists of repeatedly
calling the next() function until a StopIteration is raised, so there
should not really be any difference.
Another thing I noticed is that if I do not let A inherit from 'object'
(removing the calls to super(..) and adding appropriate initalization of
self.n), the result is as expected.
I am completely puzzled, so if anybody could shed some light on this,
I'd appreciate this.
YVES
I was fiddling around a bit with iterators and I came across some
strange behaviour. I have the following simple code:
--
class A(object):
def __init__(self, n):
self.n = n
def __iter__(self):
return self
def next(self):
if self.n > 0:
self.n -= 1
return "A: %d" % self.n
else:
raise StopIteration()
class B(A):
def __init__(self, n):
super(B,self).__init__(n)
def __iter__(self):
return self
def next(self):
if self.n > 0:
self.n -= 1
return "B: %d" % self.n
else:
raise StopIteration()
class C(A):
def __init__(self, n):
super(C,self).__init__(n)
self.next = self.mynext
def __iter__(self):
return self
def mynext(self):
if self.n > 0:
self.n -= 1
return "C: %d" % self.n
else:
raise StopIteration()
if __name__=='__main__':
a = A(2)
b = B(2)
c = C(2)
for k in [a,b,c]:
# Iterate over the object
for i in k:
print i
print "="*50
--
The output I expected was
A: 1
A: 0
==================================================
B: 1
B: 0
==================================================
C: 1
C: 0
==================================================
but strangely enough I ended up with
A: 1
A: 0
==================================================
B: 1
B: 0
==================================================
A: 1
A: 0
==================================================
Or in other words, it appears that Python does not use 'mynext' when
iterating over an object of class C. When I call c.next() directly
though, it does execute the code from the 'mynext' method. In my
understanding, iterating over a list, simply consists of repeatedly
calling the next() function until a StopIteration is raised, so there
should not really be any difference.
Another thing I noticed is that if I do not let A inherit from 'object'
(removing the calls to super(..) and adding appropriate initalization of
self.n), the result is as expected.
I am completely puzzled, so if anybody could shed some light on this,
I'd appreciate this.
YVES