GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing pythonprogramming.net — Python Programming Tutorials Special Methods, OOP, and Iteration Python TutorialWelcome to part 21 of the intermediate Python programming tutorial series. In this tutorial, we're going to take a unique opportunity to mesh OOP, iterables, iterators, special methods, AND generators. It's an exciting day. There are all sorts of special methods that we can add to our classes, but one common one might be to either add iteration functionality, or even to modify how something is iterated over. Let's revisit When we do something like: x = range(5) What is Is there a difference between Let's say: x = (i for i in range(5)) Now, how do we for i in x:
print(i)
Output: 0 1 2 3 4 What happens here, I mean *really*? As you x = (i for i in range(5))
next(x)
next(x)
for i in x:
print(i)
Output: 2 3 4 With x = (i for i in range(5))
x.__next__()
x.__next__()
for i in x:
print(i)
Output: 2 3 4 Works the same way. Jeez >>> print(dir(x)) ['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw'] !!!!!!!! Look at all of those dunders that >>> print(dir(range)) ['__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index', 'start', 'step', 'stop'] Sheesh. We can trust no one. We need to handle this iteration stuff on our own, clearly. Let's make a new class, called class range_examp:
def __init__(self, end, step=1):
self.current = 0
self.end = end
self.step = step
Any good range function is going to need to know where it is and where to head next. Other than that, it doesn't need much else, but we'll also give it a stopping point. Now, let's do the entirely challenging task of writing the def __iter__(self):
return self
Whew, that was hard. Now we need to write the dunder next method. def __next__(self):
if self.current >= self.end:
raise StopIteration()
else:
return_val = self.current
self.current += self.step
return return_val
Simple enough above. If the current value is at or beyond the end value, then we're done, and we raise a for i in range_examp(5):
print(i)
0 1 2 3 4 Fancy! We can also illustrate the use of i = range_examp(5)
i.__next__()
i.__next__()
for j in i:
print(j)
Output: 2 3 4 Of course, we still have a lot of hidden attributes to even this new class that we just made... >>> print(dir(range_examp)) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] ...not to mention that def range_gen(end):
current = 0
while current < end:
yield current
current += 1
Perfect, good ol' functions. No classes here. We can do something like: for i in range_gen(5):
print(i)
Output: 0 1 2 3 4 But then again... >>> print(dir(range_gen(5))) ['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw'] There's no getting away from Object Oriented Programming in Python 3!
|
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |