如果我有一个使用 yield 的 cdef 或 cpdef 函数,它应该是什么类型?

If I have a cdef or cpdef function which uses yield, what type should it be?

好的,我有一个生成器函数(一个使用 yield 语句的函数)。

具体来说,这是我正在努力让 Python 玩数独游戏的 Cythonized 的一部分。 (是的,这是微不足道的,但这是我现在正在做的事情,它与其他事情有关。)

这是建立上下文的第 1 部分。第 2 部分是数独网格存储为单元格列表的列表(扩展类型,因为我可以这样做,为此它也可能是一个智能整数,可以计算出它可以,甚至应该基于其他已经被提供给它的实例 - 无论如何)。

这是有问题的代码部分:

cpdef box_gen(self):
    cdef:
        unsigned char y1, x, y2
        list box
    for y1 in range(0,9,3):
        for x in range(0,9,3):
            box = []
            for y2 in range(y1,y1+3):
                box.extend(self.grid[y2][x:x+3])
            yield [cell.c for cell in box]
cpdef row_gen(self):
    cdef:
        list row
    for row in self.grid:
        yield [x.c for x in row]
cpdef col_gen(self):
    cdef:
        char i
    for i in range(9):
        yield [row[i].c for row in self.grid]

哦,另外,Cell 的数值(如果尚未确定或分配,则为 0)存储在属性 'c'.

所以:我应该将这些函数键入什么?有没有我需要从 cpython 导入的类型?使用 cdef extern 块有什么我需要抓住的吗?

感谢您的宝贵时间。

这不起作用 - 您只能使用具有 def 函数的生成器。

解释为什么使用 cdef 函数对他们来说没有意义:cdef 函数产生可以直接转换为 C 函数签名的东西

cdef int f(float y):
   #... 

变成(带有一些名称修改)

int f(float y) {
   // ...
}

生成器(以及内部函数)必然有一些内部状态来跟踪它在闭包中的位置以及哪些变量已被更改。这将在 C 中表示为至少两个函数

 some_opaque_structure_type* prepare_generator_f(float y) {
    // ...
 }

 int use_generator_f(some_opaque_structure_type* s) {
     // ...
 }

(这忽略了如何发出迭代已完成的信号,或者如何 pass data back into the iterator, or the result = yield from some_other_generator syntax

尽管 none 无法实现,但它会破坏 link 的“cdef 函数具有明确的 C 签名,因此可以作为 C 函数传递指针或很容易被 user-defined C 代码使用”。 cdef 函数有一组限制,使它们能够从 Cython 中更有效地调用它们,因此它们不能做 Python def 函数可以做的所有事情是有道理的。


只需使用一个def函数。