一:使用环境
前不久在写行为树框架的时候,有一个需求。比如某一个节点是判断node的各个数字的大小,根据判断结果做出决策,配置文件如下。
需要获取当前执行节点的hp和attack的值 然后 格式化进args的value中,比如说hp是100,attack是100,那么代码里边就是要判断 100 > 50 and 100 < 50的值了,这个时候就要用到Python的eval了。
二:eval使用说明
eval是Python的内置函数,作用就是返回传入字符串的表达式的结果。
原型:eval(expression[, globals[, locals]])
expression : 表达式,可以是字符串 也可以是一个任意的code(代码)对象实例(可以通过complie函数创建)
globals : 变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。
locals : 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。
返回值:
如果expression 是一个code对象,且创建该code对象时,complie函数的mode参数是‘exec’,那么eval()函数的返回值是None;否则,如果source是一个输出语句,如print(),则eval()返回结果为None;否则,source表达式的结果就是eval()函数的返回值
上实例:
locals为空 globals不为空时 查找globals参数中是否存在变量并计算
当两个参数都不为空时,先查找locals参数,再查找globals参数,locals参数中同名变量会覆盖globals中的变量。
通常用法
a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]"
b = eval(a)
b#[[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]
type(b)#list
a = "{1: 'a', 2: 'b'}"
b = eval(a)
b#{1: 'a', 2: 'b'}
type(b)#dict
a = "([1,2], [3,4], [5,6], [7,8], (9,0))"
b = eval(a)
b#([1, 2], [3, 4], [5, 6], [7, 8], (9, 0))
三:eval使用危险之处
eval虽然方便,但是要注意安全性,可以将字符串转成表达式并执行,就可以利用执行系统命令,删除文件等操作。
假设用户恶意输入。比如:
eval("__import__('os').system('dir C:\python27')")
相当于执行了 os.system('dir C:\python27')
在Linux中这就是很危险的了 比如
eval("__import__('os').system('cat /XXX/tls_asimov_cert.pem')")
秘钥都被别人查看了
eval("__import__('os').system('rm /XXX/XXXXXX.png')")
文件都被别人删除了