Python函数内字典推导式用eval调用变量触发NameError问题
报错原因
- 核心问题是 Python 3 中的字典推导式拥有独立的嵌套作用域,和函数的本地作用域相互隔离。
eval()执行时默认只会查找当前执行上下文的作用域、全局作用域,无法直接访问推导式外层的函数本地变量。 - 你逐行执行代码时,
primes_cols等变量都定义在全局作用域,推导式可以正常访问全局变量,所以不会报错;代码封装进函数后,primes_cols等变量属于函数本地作用域,推导式内的eval()无法检索到这些变量,就抛出了NameError。 - 额外说明:生产环境不建议随意使用
eval(),该函数存在代码注入的安全隐患,且当前场景完全有更稳妥的替代写法。
修复方案
方案1:用列映射字典替代eval(最推荐)
完全规避eval的所有问题,代码可读性和安全性都更高:
import pandas as pd primes = pd.DataFrame(columns = ['A','B','C','D'], data=[[3,5,7,11]]) tens = pd.DataFrame(columns = ['E','F','G','H'], data=[[10,20,30,40]]) evens = pd.DataFrame(columns = ['I','J','K','L'], data=[[4,8,12,16]]) def process(): keys = ['primes','tens','evens'] # 提前定义每个key对应的保留列,替代分散的xxx_cols变量 col_mapping = { 'primes': ['A','B'], 'tens': ['E','F'], 'evens': ['I','J'] } data = {key:eval(key) for key in keys} # 直接从映射字典取列,不需要eval data = {key:value[col_mapping[key]] for (key, value) in data.items()} return data df = process()
方案2:手动给eval传入本地命名空间
如果要保留现有变量定义逻辑,只需要给eval手动传入函数的本地作用域即可:
仅修改推导式那一行代码:
data = {key:value[eval(key + '_cols', globals(), locals())] for (key, value) in data.items()}
手动指定eval查找变量的全局、本地命名空间后,就能正常识别函数内定义的primes_cols等变量了。
内容的提问来源于stack exchange,提问作者Les_Zee
相关产品推荐
相关产品推荐

