这是代码:
var holderelement=document.body;
var howmanylinksyouwant=3;
for (var i=0;i<howmanylinksyouwant;i++){
var li=document.createElement("li");
li.onclick=function(){location.href="stackoverflow.com";}
li.style.textAlign="center";
li.innerHTML="<b>ep "+i+"</b>" holderelement.append(li);
}
如果你运行它,你会看到:
def g():
try:
yield 1
yield 2
yield 3
except GeneratorExit:
yield 4
gen = g()
print(gen.__next__())
我理解发生了什么,但我找不到这个警告的消息类型。
看起来它不是1
Exception ignored in: <generator object g at 0x00000216BB546A98>
RuntimeError: generator ignored GeneratorExit
警告(我无法删除它设置日志记录级别)。它也不是logging
警告(它看起来不像我们在调用warnings
时得到的那样)。
我认为它可以与异常相关联,但我无法用warnings.warn
来捕捉它,而msg本身就消失了:
sys.excepthook
我怎样才能听到这个警告?
如何手动创建此类警告?
答案 0 :(得分:6)
有些人已经注意到,并非每个人都能得到你所描述的行为。例如,您在REPL中无法获得此行为。要在REPL上重现此行为,您必须在末尾添加del gen
。这让我们知道警告的来源。警告来自发电机对象的清理功能,发现发电机没有干净地退出。
具体发生的是,当解释器正在尝试清理发生器并释放其资源时,生成器引发了异常。解释器无法传播此异常,因此它会记录此状态并继续。具体来说,正在调用PyErr_WriteUnraisable。 here就是如何调用它(我的评论)。
void
_PyGen_Finalize(PyObject *self)
{
...
if (gen is a coroutine) {
// special error detecting logic for coroutines
}
else {
res = gen_close(gen, NULL); // <- raises GeneratorExit
}
if (res == NULL) {
if (PyErr_Occurred()) {
PyErr_WriteUnraisable(self);
}
}
else {
Py_DECREF(res);
}
...
}
答案 1 :(得分:0)
当我运行你的代码时,我得到:
1
>>>
没有错误(我也在Windows 10上使用Python 3.5.1), 但您可以使用以下代码来确定代码中的错误:
try:
a = int('a') # here you can put your code
except Exception as e:
print(e) # this prints error message
print(type(e).__name__) # this prints name of your error
在这种情况下,你得到这个输出:
invalid literal for int() with base 10: 'a'
ValueError
>>>
所以现在你可以使用:
来捕捉错误to_convert = 'a'
try:
a = int(to_convert)
except ValueError:
print(to_convert, 'can\'t be converted to string.')
通过查看您的错误消息,我认为您对RuntimeError
而不是GeneratorExit
存在问题。
希望它有所帮助。
编辑:
正如@interjay在评论中说的那样,当我运行你的代码生成器时,对象并没有被破坏,所以没有错误。
问题是当python破坏生成器对象时,在执行此代码时会调用generator.close()
产生错误:
def g():
try:
yield 1
yield 2
yield 3
except GeneratorExit:
yield 4
gen = g()
print(gen.__next__())
gen.close()
你得到:
RuntimeError: generator ignored GeneratorExit
>>>
但是当生成器对象被销毁(删除)时,异常被忽略。
要避免此警告,您可以在代码中调用generator.close()
然后捕获错误,因此您的代码应如下所示:
def g():
try:
yield 1
yield 2
yield 3
except GeneratorExit:
yield 4
gen = g()
print(gen.__next__())
try:
gen.close()
except RuntimeError:
pass