如何在pd.eval或df.eval中暴露str等Python内置对象?
解决pandas eval中通过@前缀调用Python内置对象的问题
pandas的eval(包括pd.eval和df.eval)默认只会捕获当前locals()和globals()中的对象,而Python内置对象(比如str)属于builtins模块,不在这两个命名空间里,因此直接用@str会触发未定义变量错误。以下是几种可行的解决方法:
方法1:手动注入到全局命名空间
这是你当前使用的临时方案,直接把str添加到globals()字典中,让eval能识别到:
import pandas as pd # 将内置str对象注入全局命名空间 globals()['str'] = str df = pd.DataFrame({'a': [1, 2, 3, 4]}) res = df.eval('a.astype(@str)', engine='python') print(res) # 输出:0 1 # 1 2 # 2 3 # 3 4 # Name: a, dtype: object
注意:这种方法会修改全局命名空间,可能带来潜在的命名冲突,不推荐在复杂项目中频繁使用。
方法2:使用local_dict参数(推荐)
利用df.eval的local_dict参数,仅在当前eval调用中注入需要的内置对象,不会污染全局空间:
import pandas as pd df = pd.DataFrame({'a': [1, 2, 3, 4]}) # 通过local_dict传入str对象 res = df.eval('a.astype(@str)', engine='python', local_dict={'str': str}) print(res)
这种方式更安全灵活,适合仅在个别eval调用中需要内置对象的场景。
方法3:批量注入多个内置对象
如果需要同时使用多个内置对象,可以从builtins模块批量提取并传入:
import pandas as pd import builtins df = pd.DataFrame({'a': [1, 2, 3, 4]}) # 按需选择需要注入的内置对象 required_builtins = ['str', 'int', 'float', 'list'] local_objs = {name: getattr(builtins, name) for name in required_builtins} res = df.eval('a.astype(@str)', engine='python', local_dict=local_objs) print(res)
这种方法适合需要频繁使用多个内置对象的场景,避免重复手动添加。
内容的提问来源于stack exchange,提问作者mihovg93
相关产品推荐
相关产品推荐

