在IPython中,通过简单地定义Cython类的属性然后调用:
,我可以看到Cython类的属性是生成器。%%cython
cdef class SomeCls:
property x:
def __get__(self):
yield 1
通话看起来像
SomeCls().x
# prints <generator at 0x102f61ee8>
我无法测试该属性是否是生成器:
import types
print(isinstance(SomeCls().x, types.GeneratorType))
# prints False
import inspect
print(inspect.isgeneratorfunction(SomeCls.x))
# prints False
如何确定Cython类的属性是否是生成器?
答案 0 :(得分:2)
为什么通常的方法不起作用?
首先,您可能已经知道,<template v-for="term in terms">
<label>
<input type="radio" value="Yes" v-model="terms[$index].termBoolean" />Yes
<input type="radio" value="No" v-model="terms[$index].termBoolean" />No
</label><br>
</template>
和inspect.isgeneratorfunction(...)
之间没有区别-检查模块只是calls isinstance(..., types.GeneratorType)
。
另一方面,isinstance(..., types.GeneratorType)
是defined as
types.GeneratorType
CPython将PyGenObject(here code,here documentation)用于生成器,对于某些ABC类,没有比较理想的逻辑,因此def _g():
yield 1
GeneratorType = type(_g())
可以归结为比较C对象类型。
但是,Cython会为生成器返回一个__pyx_CoroutineObject
(只需查看经过Cythonized验证的代码即可)
isinstance
就typedef PyObject *(*__pyx_coroutine_body_t)(PyObject *, PyThreadState *, PyObject *);
typedef struct {
PyObject_HEAD
__pyx_coroutine_body_t body;
PyObject *closure;
...
int resume_label;
char is_running;
} __pyx_CoroutineObject;
而言,它与PyGenObject
无关-它实际上并不在乎isinstance
是否是类型名称(但对于我们人类来说,它是可能确实令人困惑,因为generator
表示“发电机”。
因此,您必须推出自己的type(obj)
版本,该版本还考虑了Cython-“ generators”。有很多方法,例如
isgenerator
现在:
%%cython
def _f():
yield 1
CyGeneratorType = type(_f())
def iscygenerator(o):
return isinstance(o, CyGeneratorType)