Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I make my class play nice with the Python '"in" keyword?

Tags:

python

I'm heading into hour 5 or so of my experience with Python, and so far I've been pretty impressed with what it can do. My current endeavor is to make a short attempt at a Stream class, the code for which follows:

class Stream:

    """A Basic class implementing the stream abstraction. """

    def __init__(self,data,funct):
        self.current = data
        self._f = funct

    def stream_first(self):
        """Returns the first element of the stream"""
        return self.current

    def stream_pop(self):
        """Removes and returns the first element of the stream. """
        temp = self.current
        self.current = self._f(self.current)
        return temp

Enjoying modest success there, I tried to make a BoundedStream class which behaves basically like the unbounded one, except that at a certain point it runs out of elements. My question now is, seeing that any such Bounded Stream has some finite number of elements, it should be possible to iterate over them. If I were using an explicit list, I could use Python's in keyword and a for loop to do this cleanly. I would like to preserve that cleanliness for my own class. Is there some method I could implement, or any other language feature, that would allow me to do this? Any answers or other help you might provide to a rookie would be greatly appreciated!

-David

P.S.

For those who want to know, the impetus for a Bounded Stream is that I tried the builtin range function, but Python claimed that the range I wanted to look at was too large. I have turned to Streams in the interest of memory efficiency.

like image 918
David Avatar asked Nov 30 '22 09:11

David


1 Answers

For iterating as in for x in object, you need to provide an __iter__ method which will return a new iterator.

An iterator is an object which has a method next() (Python 2) or __next__ (Python 3) which either returns the next element or raises StopIteration exception when there are no more elements. (An iterator should also have a method __iter__ that returns itself.)

Tip: You don't often need to code an iterator by yourself; the simplest way to implement __iter__ on a class is to make it a generator function or to return a generator expression from it (all generators are iterators). Also you can just return an iterator obtained from another object; the iter builtin is helpful here.


For testing if x in object, you need to provide a __contains__ method.

Further reading: Python data model - emulating container types

like image 97
Kos Avatar answered Dec 05 '22 18:12

Kos