Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python - support .send() for a class?

Writing a class, how do I implement

foo.send(item) ?

__iter__ allows iterating over the class like a generator, what if I want it to be a coroutine?

like image 622
justin cress Avatar asked Dec 13 '10 21:12

justin cress


People also ask

Can a class have a parameter Python?

Python Class Object At first, you put the name of the new object which is followed by the assignment operator and the name of the class with parameters (as defined in the constructor). Remember, the number and type of parameters should be compatible with the parameters received in the constructor function.

What is __ class __ in Python?

__class__ is an attribute on the object that refers to the class from which the object was created. a. __class__ # Output: <class 'int'> b. __class__ # Output: <class 'float'> After simple data types, let's now understand the type function and __class__ attribute with the help of a user-defined class, Human .

How do you pass a class to another class in Python?

To create a class that inherits from another class, after the class name you'll put parentheses and then list any classes that your class inherits from. In a function definition, parentheses after the function name represent arguments that the function accepts.

What is __ add __ in Python?

Python __add__() function is one of the magic methods in Python that returns a new object(third) i.e. the addition of the other two objects. It implements the addition operator “+” in Python.


1 Answers

Here is a basic example of a coroutine:

def coroutine(func):
    def start(*args,**kwargs):
        cr = func(*args,**kwargs)
        cr.next()
        return cr
    return start

@coroutine
def grep(pattern):
    print "Looking for %s" % pattern
    while True:
        line = (yield)
        if pattern in line:
            print(line)

g = grep("python")
# Notice how you don't need a next() call here
g.send("Yeah, but no, but yeah, but no")
g.send("A series of tubes")
g.send("python generators rock!")
# Looking for python
# python generators rock!

We can make a class which contains such a coroutine, and delegates calls to its send method to the coroutine:

class Foo(object):
    def __init__(self,pattern):
        self.count=1
        self.pattern=pattern
        self.grep=self._grep()
    @coroutine
    def _grep(self):
        while True:
            line = (yield)
            if self.pattern in line:
                print(self.count, line)
                self.count+=1
    def send(self,arg):
        self.grep.send(arg)

foo = Foo("python")
foo.send("Yeah, but no, but yeah, but no")
foo.send("A series of tubes")
foo.send("python generators rock!")
foo.pattern='spam'
foo.send("Some cheese?")
foo.send("More spam?")

# (1, 'python generators rock!')
# (2, 'More spam?')

Notice that foo acts like a coroutine (insofar as it has a send method), but is a class -- it can have attributes and methods which can interact with the coroutine.

For more information (and wonderful examples), see David Beazley's Curious Course on Coroutines and Concurrency.

like image 176
unutbu Avatar answered Sep 28 '22 00:09

unutbu