python - Python3:列表推导和堆栈框架
问题描述
考虑这个函数:
def quux():
i = 42
print([i for x in [1]])
结果:[42]
因此,我假设本地变量在列表推导中是可见的。
现在考虑一下:
def foo():
return currentframe().f_back.f_locals["i"]
def quux():
i = 42
print([foo() for x in [1]])
导致:
键错误:'我'
检查堆栈帧,事实证明在 quux 和 foo 的帧之间插入了一个额外的堆栈:
{'x': 1, '.0': <tuple_iterator object at 0x7f59eb94c860>}
好,可以。我感到困惑的是为什么第一个例子看到i
. 如果有一个额外的堆栈框架,它不应该是可见的,不是吗?
从更实际的角度来看,我如何获得调用函数的堆栈框架,而不管我的函数是从没有或从列表推导中调用的,或者就此而言,是从多个嵌套列表推导中调用的?
解决方案
这是一个非常好的观察(不管它的用处:))。回答您的问题的最佳方法是亲自查看:转储反汇编(dis.dis(quux)
在两个版本中使用)。您会注意到两个版本的重要区别是在第一个版本中加载的闭包。这是因为您在列表理解对象中引用了变量 i ,并且通过这样做您使 ia 成为闭包的一部分,并且列表 comp 可以访问它。在第二种情况下,没有这样的事情,所以你得到那个错误。
对于第二部分,既然您理解了,您可能想重新措辞一下?
推荐阅读
- android - Socket.io 连接问题
- mongodb - Mongo 聚合 $group _id 是一个数组
- c# - 无法从 Compilation 对象获取 SyntaxTree
- html - 不同设备中的字体更改
- javascript - Vue.js 中的 Revolution Slider jquery 插件
- google-sheets - 突出显示 Google 表格中前 x 行的列中的重复值
- odoo - 在将值设置为必填字段之前,odoo 按钮定义不起作用
- java - 从服务器肥皂故障异常中提取文本内容
- c++ - 我可以自定义一个元素是结构的流吗
- jenkins - Jenkins 只执行 groovy 闭包的第一行