eval 是干嘛的?
解析字符串表达式并执行,并返回一个值
语法格式
eval(expression[, globals[, locals]])
- expression:表达式字符串
- globals:必须是一个字典
- locals:可以是任何 map 对象
最简单的表达式栗子
栗子一
print(eval(\"123\"))print(eval(\"True\"))print(eval(\"(1,2,3)\"))print(eval(\"[1,2,3]\"))# 输出结果123True(1, 2, 3)[1, 2, 3]
栗子二
print(eval(\"1+2\"))x = 1print(eval(\'x+1\'))# 输出结果32
栗子三
a = 1b = 2print(eval(\"[a,b]\"))# 输出结果[1, 2]
带上 globals
# 使用 globalsx = 10g = {\"x\": 5}print(eval(\"x+1\", g))# 输出结果6
在 eval 中提供了globals 参数
eval 的作用域就是 g 指定的这个字典,外面的 x = 10 被屏蔽掉了,eval 是看不见的,所以使用了 x 为 5 的值
x = 10y = 5g = {\"x\": 5}print(eval(\"x+1+y\", g))# 输出结果5print(eval(\"x+1+y\", g))File \"<string>\", line 1, in <module>NameError: name \'y\' is not defined
因为 global 参数没有 y 变量值,所以报错了
带上 locals
# 使用 localsa = 1g = {\"a\": 2, \"b\": 3}l = {\"b\": 30, \"c\": 4}print(eval(\"a+b+c\", g, l))# 输出结果36
- eval 的作用域变成了 globals + locals
- locals 作用域优先级会高于 globals
- locals 参数里面的值会覆盖 globals 参数里面的值
字符串转字典
# 字符串转字典jsons = \"{\'a\':123,\'b\':True}\"print(type(eval(jsons)))# 输出结果<class \'dict\'>
带上 globals
print(eval(\"{\'name\':\'linux\',\'age\':age}\", {\"age\": 123}))# 输出结果{\'name\': \'linux\', \'age\': 123}
带上 locals
print(eval(\"{\'name\':\'linux\',\'age\':age}\", {\"age\": 123}, {\"age\": 24}))# 输出结果{\'name\': \'linux\', \'age\': 24}
内置函数栗子
# 内置函数print(eval(\"dir()\"))print(eval(\"abs(-10)\"))# 输出结果[\'__annotations__\', \'__builtins__\', \'__cached__\', \'__doc__\', \'__file__\', \'__loader__\', \'__name__\', \'__package__\', \'__spec__\', \'a\', \'b\', \'g\', \'jsons\', \'l\', \'x\', \'y\']10
报错的栗子
栗子一
print(eval(\"aa\"))# 输出结果print(eval(\"aa\"))File \"<string>\", line 1, in <module>NameError: name \'aa\' is not defined
栗子二
print(eval(\"[a,b,c]\"))# 输出结果print(eval(\"[a,b,c]\"))File \"<string>\", line 1, in <module>NameError: name \'c\' is not defined
栗子三
print(eval(\"if x: print(x)\"))# 输出结果print(eval(\"if x: print(x)\"))File \"<string>\", line 1if x: print(x)^SyntaxError: invalid syntax
- 因为 eval() 只接受表达式
- 任何其他语句(如if、for、while、import、def、class)都将引发错误