You are here
Python iterators considered harmful
Liraz Siri - Mon, 2011/07/11 - 14:01 -
7 comments
I just tracked down a nasty bug in my code to a gotcha with Python iterators.
Consider the following code...
class Numbers(list):
def even(self):
for val in self:
if val % 2 == 0:
yield val
even = property(even)
def odd(self):
for val in self:
if val % 2 != 0:
yield val
odd = property(odd)
nums = Numbers(range(10))
# [0, 2, 4, 6, 8]
print `list(nums.even)`
# [0, 2, 4, 6, 8]
print `list(nums.even)`
even = nums.even
# [0, 2, 4, 6, 8]
print `list(even`)
# GOTCHA!
# []
print `list(even`)
This is evil. Watch out for it. In this example, if you don't actually need iterators you could just as easily rewrite Numbers using list comprehension:
class Numbers(list):
def even(self):
return [ val for val in self if val % 2 == 0 ]
even = property(even)
def odd(self):
return [ val for val in self if val % 2 != 0 ]
odd = property(odd)
No subtle gotchas and the code is even shorter!
Add new comment