python属性是什么意思_Python 生成器对象的属性的含义?

找到相关的源码了,虽然看不懂:

static PyObject *

gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)

{

PyThreadState *tstate = PyThreadState_GET();

PyFrameObject *f = gen->gi_frame;

PyObject *result;

if (gen->gi_running) {

const char *msg = "generator already executing";

if (PyCoro_CheckExact(gen)) {

msg = "coroutine already executing";

}

else if (PyAsyncGen_CheckExact(gen)) {

msg = "async generator already executing";

}

PyErr_SetString(PyExc_ValueError, msg);

return NULL;

}

if (f == NULL || f->f_stacktop == NULL) {

if (PyCoro_CheckExact(gen) && !closing) {

/* `gen` is an exhausted coroutine: raise an error,

except when called from gen_close(), which should

always be a silent method. */

PyErr_SetString(

PyExc_RuntimeError,

"cannot reuse already awaited coroutine");

}

else if (arg && !exc) {

/* `gen` is an exhausted generator:

only set exception if called from send(). */

if (PyAsyncGen_CheckExact(gen)) {

PyErr_SetNone(PyExc_StopAsyncIteration);

}

else {

PyErr_SetNone(PyExc_StopIteration);

}

}

return NULL;

}

if (f->f_lasti == -1) {

if (arg && arg != Py_None) {

const char *msg = "can't send non-None value to a "

"just-started generator";

if (PyCoro_CheckExact(gen)) {

msg = NON_INIT_CORO_MSG;

}

else if (PyAsyncGen_CheckExact(gen)) {

msg = "can't send non-None value to a "

"just-started async generator";

}

PyErr_SetString(PyExc_TypeError, msg);

return NULL;

}

} else {

/* Push arg onto the frame's value stack */

result = arg ? arg : Py_None;

Py_INCREF(result);

*(f->f_stacktop++) = result;

}

/* Generators always return to their most recent caller, not

* necessarily their creator. */

Py_XINCREF(tstate->frame);

assert(f->f_back == NULL);

f->f_back = tstate->frame;

gen->gi_running = 1;

gen->gi_exc_state.previous_item = tstate->exc_info;

tstate->exc_info = &gen->gi_exc_state;

result = PyEval_EvalFrameEx(f, exc);

tstate->exc_info = gen->gi_exc_state.previous_item;

gen->gi_exc_state.previous_item = NULL;

gen->gi_running = 0;

/* Don't keep the reference to f_back any longer than necessary. It

* may keep a chain of frames alive or it could create a reference

* cycle. */

assert(f->f_back == tstate->frame);

Py_CLEAR(f->f_back);

/* If the generator just returned (as opposed to yielding), signal

* that the generator is exhausted. */

if (result && f->f_stacktop == NULL) {

if (result == Py_None) {

/* Delay exception instantiation if we can */

if (PyAsyncGen_CheckExact(gen)) {

PyErr_SetNone(PyExc_StopAsyncIteration);

}

else {

PyErr_SetNone(PyExc_StopIteration);

}

}

else {

/* Async generators cannot return anything but None */

assert(!PyAsyncGen_CheckExact(gen));

_PyGen_SetStopIterationValue(result);

}

Py_CLEAR(result);

}

else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) {

const char *msg = "generator raised StopIteration";

if (PyCoro_CheckExact(gen)) {

msg = "coroutine raised StopIteration";

}

else if PyAsyncGen_CheckExact(gen) {

msg = "async generator raised StopIteration";

}

_PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);

}

else if (!result && PyAsyncGen_CheckExact(gen) &&

PyErr_ExceptionMatches(PyExc_StopAsyncIteration))

{

/* code in `gen` raised a StopAsyncIteration error:

raise a RuntimeError.

*/

const char *msg = "async generator raised StopAsyncIteration";

_PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);

}

if (!result || f->f_stacktop == NULL) {

/* generator can't be rerun, so release the frame */

/* first clean reference cycle through stored exception traceback */

exc_state_clear(&gen->gi_exc_state);

gen->gi_frame->f_gen = NULL;

gen->gi_frame = NULL;

Py_DECREF(f);

}

return result;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值