- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试获取 Python 中生成器执行的最后一行的数量。我找到了在几种情况下获得它的方法:
产量
而暂停,StopIteration
),StopIteration
返回的生成器。但是我想询问如何在生成器执行 return
语句或刚刚到达最后一行后自动引发 StopIteration
的情况下获取行号相应的功能。
下面列出了我使用的简化代码示例。
from sys import exc_info
def gen1():
print("1.1")
yield
print("1.2")
raise StopIteration()
def gen2():
print("2.1")
yield
print("2.2")
return
def gen3():
print("3.1")
yield
print("3.2")
raise RuntimeError()
for gen in [ g for n, g in globals().items() if n.startswith("gen") ]:
g = gen() # launch the generator
while True:
try:
next(g)
except StopIteration: # generator normally returned
tb = exc_info()[2].tb_next
if tb is None:
print("How to get last line?")
else:
print("last line: %s" % tb.tb_frame.f_lineno)
break
except BaseException: # generator failure
tb = exc_info()[2].tb_next
print("last line: %s" % tb.tb_frame.f_lineno)
break
else:
print("last line: %s" % g.gi_frame.f_lineno)
执行此代码返回:
3.1
last line: 17
3.2
last line: 19
2.1
last line: 11
2.2
How to get last line?
1.1
last line: 5
1.2
last line: 7
最佳答案
您想要的信息位于框架对象中。
但是框架对象已经被垃圾回收了。 g.gi_frame
中对它的引用设置为None
当函数返回时。
回溯不会帮助你,因为回溯来自函数返回后解释器内部的机器,所以它无处可获取它(并且你已经看到它甚至没有尝试)。
<小时/>但是如果您可以更改代码以获取对 gi_frame
的引用在生成器运行时保存对象并在生成器完成后保留它,您将保持该对象以及所有其他相关垃圾的事件。
这意味着f_lineno
可能是有效的,正如您在最后一个从未发生过的情况中所使用的那样。不知道有没有办法查到f_lineno
什么时候是并且没有意义,但是如果您深入研究其源代码,回溯生成代码可能会知道这一点。
如果没有,f_lasti
肯定是 RETURN_VALUE
的字节码偏移量作品。 Python 当然不能保证它不会对 lasti
做任何奇怪的事情。在发布框架之前,但它还没有出现在任何版本中,而且很难看出将来有什么理由这样做。因此,使用 f_code.co_lnotab
中的信息应该始终是正确的。生成 f_lasti
的行号。请参阅dis
模块寻求帮助。 (如果您的 Python 足够新,它会公开 findlinestarts
来为您完成此操作;如果没有,请阅读模块的源代码。或者从解释器源代码的 Objects
目录中的文档编写您自己的 lnotab 解析器,如果你想要一些真正的乐趣。)
关于python - 如何在 Python 中获取生成器执行的最后一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49710035/
我是一名优秀的程序员,十分优秀!