Welcome, guest | Sign In | My Account | Store | Cart

This recipe is a simple pair of classes that implement something like what is proposed for <a href="http://www.python.org/peps/pep-0342.html">PEP 342</a>, but with a few differences. For one, you can send any signature, not just one object. You are able to pass any number of positional and keyword arguments through the send method. Also, this does not address a close method, but one could be easily added.

Python, 40 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class channel(object):
  def __init__(self, gen):
    self.gen = gen
    self.args = ()
    self.kwargs = {}
  def __iter__(self):
    return self
  def next(self):
    self.args = ()
    self.kwargs = {}
    return self.gen.next()
  def send(self, *args, **kwargs):
    self.args = args
    self.kwargs = kwargs
    return self.gen.next()

class channelgen(object):
  def __init__(self, genfunc):
    self.genfunc = genfunc
  def __call__(self, *args, **kwargs):
    c = channel(None)
    c.gen = self.genfunc(c, *args, **kwargs)
    return c

# A simple example

@channelgen
def skipper(chan, seq, skip = 0):
  for i in seq:
    if skip:
      skip -= 1
    else:
      yield i
      if chan.args:
        skip = chan.args[0]

skip = skipper(xrange(100))
skip.next()
skip.next()
skip.send(10) # Skips ten items in the sequence before yeilding one

I chose to name them channel and channelgen, in the idea that we are using a communications channel between the code calling the generator and the generator itself. I really like the idea of doing this, and until 342 gets accepted, I wanted a way to make use of the concept and to easily port my solution to the actual implementation when its available.

Created by Calvin Spealman on Mon, 25 Jul 2005 (PSF)
Python recipes (4591)
Calvin Spealman's recipes (1)

Required Modules

  • (none specified)

Other Information and Tasks