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

时间:2018-02-23 03:35:09

标签: python-3.x cython yield typing

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

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

这是建立背景的第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块来绘制一些东西吗?

感谢您的时间。

1 个答案:

答案 0 :(得分:1)

这不起作用 - 您只能使用具有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 iteratorresult = yield from some_other_generator syntax

虽然这些都不可能实现,但它会破坏" cdef函数具有明确的C签名的链接,因此可以作为C函数指针传递或者可以被用户使用-defined C code"。 cdef函数有一组限制,可以从Cython中更有效地调用它们,因此它们可以执行Python def函数可以执行的所有操作。

只需使用def功能。