Python中如何让eval()识别局部变量?列表推导式异常原因咨询
问题底层原因
核心原因涉及Python的两条基础机制:
- Python 3中所有推导式(列表/集合/字典推导式)、生成器表达式都拥有独立的局部作用域,仅会从自身局部作用域、父级词法作用域、全局作用域查找变量
eval函数传入的locals字典是动态上下文,仅对eval执行的最顶层代码生效,推导式、内部函数这类嵌套作用域不会访问该动态传入的locals字典
两次调用的差异解释
第一次调用
foo("[i for i in value]",x)执行成功的原因:
列表推导式的for i in value中的迭代对象value,是在推导式的父作用域(也就是eval的最顶层执行上下文)中求值的,此时可以正常读取eval传入的locals字典里的value变量,因此执行正常。第二次调用报错的原因:
推导式内部的表达式x in value是在推导式自己的独立作用域中执行的,该作用域只会查找全局命名空间和推导式自身的局部变量,无法访问eval传入的动态locals字典里的value,因此抛出NameError。
绕过方案生效逻辑
你使用的lambda V=value: ...方案中,默认参数的赋值是在lambda定义阶段(也就是eval的最顶层执行上下文)完成的,直接把value的值绑定到了lambda的局部变量V上。后续lambda内部的列表推导式的父作用域是lambda的词法作用域,因此可以正常访问到lambda的局部变量V,不会触发变量未定义错误。
内容的提问来源于stack exchange,提问作者L8Cod3r
相关产品推荐
相关产品推荐

