好的,我有一个生成器函数(一个使用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
块来绘制一些东西吗?
感谢您的时间。
答案 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 iterator或result = yield from some_other_generator
syntax)
虽然这些都不可能实现,但它会破坏" cdef
函数具有明确的C签名的链接,因此可以作为C函数指针传递或者可以被用户使用-defined C code"。 cdef
函数有一组限制,可以从Cython中更有效地调用它们,因此它们可以执行Python def
函数可以执行的所有操作。
只需使用def
功能。