Python/C API

Duncan Booth duncan at NOSPAMrcp.co.uk
Thu Apr 10 11:40:38 CEST 2003


Jp Calderone <exarkun at intarweb.us> wrote in 
news:mailman.1049956515.20986.python-list at python.org:

>   How does one write generators in C, or does one not?
> 
You don't, but creating iterators has the same effect.

You need to create an iterator object with two methods __iter__ returning 
self and __next__ calculating the next value and returning it. All of the 
state must be saved in the object between calls as there is no way to save 
the C stack frame. You probably also need an __init__ method to set things 
up.

Use Pyrex or Boost in preference to the C api if you can. If you must use 
the C api directly then you are probably best looking at something liike 
itertoolsmodule.c and plagiarising the code for one of the iterator types.

Here's a pyrex example. It could be calling C functions directly, although 
for this example I didn't bother. Although it looks like Python the 
expressions all use genuine C ints.

---- Seq.pyx ---
cdef class MyGen:
    cdef int current

    def __init__(self, int initial):
        self.current = initial

    def __iter__(self):
        return self

    def __next__(self):
        cdef int current
        
        current = self.current
        if current == 1:
            raise StopIteration

        if current%2 == 0:
            self.current = self.current / 2
        else:
            self.current = 3 * self.current + 1

        return current
---- test.py ---
import Seq

for v in Seq.MyGen(7):
    print v,
print

print list(Seq.MyGen(23))
---- end ---

-- 
Duncan Booth                                             duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?




More information about the Python-list mailing list