Iterators & generators & coroutines

Evan Simpson evan at 4-am.com
Tue Feb 15 16:12:54 EST 2000


Aahz Maruch <aahz at netcom.com> wrote in message
news:88c7hu$209$1 at nntp5.atl.mindspring.net...
> As a side note, I'm thinking that implicit generator creation is a Bad
> Idea.  We should force people to do things like
>
> b = BinTree()
> g = generator b.traverse()
> for i in g():
> ....

Why attach such significance to it?  Why not just...

b = BinTree()
for node in b.traverser():

...?  While I'm at it, for general edification I present a somewhat
hacked-up version of a coroutine example originally posted long ago by Tim
Peters, and preserved at
http://www.tismer.com/research/stackless/coroutines.tim.peters.html

I changed it to use the 'suspend' syntax, along with a totally imaginary
Coroutines class.  Basically, it shows how coroutines can be used like a
pipeline; We feed 'text' in one end, it comes out the other end processed,
and one of the middle bits decides when we're all done.

def getline(text):
    'Break text into lines'
    for line in string.splitfields(text, '\n'):
        suspend line

def disassembler():
    'Break lines into characters, add ; at ends'
    while 1:
        card = co.getline()
        for c in card:
            suspend c
        suspend ';'

def squasher():
    'Replace ** with ^ and squash whitespace'
    while 1:
        ch = co.disassembler()
        if ch == '*':
            ch2 = co.disassembler()
            if ch2 == '*':
                ch = '^'
            else:
                suspend ch
                ch = ch2
        if ch in ' \t':
            while 1:
                ch2 = co.disassembler()
                if ch2 not in ' \t':
                    break
            suspend ' '
            ch = ch2
        suspend ch

def assembler():
    line = ''
    while 1:
        ch = co.squasher()
        if ch == '\0':
            break
        if len(line) == 72:
            suspend line
            line = ''
        line = line + ch
    line = line + ' ' * (72 - len(line))
    suspend line
    co.exit()

def putline():
    while 1:
        print co.assembler()

co = Coroutines(getline, disassembler, squasher, assembler, putline)
co.setup.getline(text)
co.putline()

Cheers,

Evan @ digicool





More information about the Python-list mailing list