python3 中的 eval 函数

From:http://blog.csdn.net/zhanh1218/article/details/37562167

Python:eval的妙用和滥用:https://blog.csdn.net/zhanh1218/article/details/37562167
python eval():http://www.cnblogs.com/dadadechengzi/p/6149930.html
Python eval 函数妙用:http://www.cnblogs.com/liu-shuai/p/6098246.html
Python 中 eval 带来的潜在风险:https://blog.csdn.net/u011721501/article/details/47298723
Python之 eval() 函数危险性浅析:https://www.jb51.net/article/51814.htm

eval() 函数十分强大,官方文档解释是:将字符串 string 对象 转化为有效的表达式参与求值运算返回计算结果
语法上:调用的是:eval(expression,globals=None, locals=None)返回的是计算结果
so,结合 math 当成一个计算器很好用。
可以把 list、tuple、dict 和 string 相互转化

其中:
        expression 是一个参与计算的 python 表达式
        globals 是可选的参数,如果设置属性不为 None 的话,就必须是 dictionary 对象了
        locals 也是一个可选的对象,如果设置属性不为 None 的话,可以是任何 map 对象了

python 是用命名空间来记录变量的轨迹的,命名空间是一个dictionary,键是变量名,值是变量值。

当一行代码要使用变量 x 的值时,Python 会到所有可用的名字空间去查找变量,按照如下顺序:

  • 1)局部名字空间 - 特指当前函数或类的方法。
          如果函数定义了一个局部变量 x, 或一个参数 x,Python 将使用它,然后停止搜索。
  • 2)全局名字空间 - 特指当前的模块。如果模块定义了一个名为 x 的变量,函数或类,Python 将使用它然后停止搜索。
  • 3)内置名字空间 - 对每个模块都是全局的。作为最后的尝试,Python 将假设 x 是内置函数或变量。

python 的全局名字空间存储在一个叫 globals() 的 dict 对象 中;局部名字空间存储在一个叫 locals() 的 dict 对象中。
我们可以用 print (locals()) 来查看该函数体内的所有变量名和变量值。

下面简单演示一下 eval()函数的使用:

#!usr/bin/env python
#encoding:utf-8
 
import math
 
 
def eval_test():
    l='[1,2,3,4,[5,6,7,8,9]]'
    d="{'a':123,'b':456,'c':789}"
    t='([1,3,5],[5,6,7,8,9],[123,456,789])'
    print '--------------------------转化开始--------------------------------'
    print type(l), type(eval(l))
    print type(d), type(eval(d))
    print type(t), type(eval(t))
 
if __name__=="__main__":
    eval_test()

运行结果为:

--------------------------转化开始--------------------------------
<type 'str'> <type 'list'>
<type 'str'> <type 'dict'>
<type 'str'> <type 'tuple'>
[Finished in 0.2s]

a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]"
b = eval(a)
b
Out[3]: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]

type(b)
Out[4]: list
 
a = "{1: 'a', 2: 'b'}"
b = eval(a)
b
Out[7]: {1: 'a', 2: 'b'}
 
type(b)
Out[8]: dict
 
a = "([1,2], [3,4], [5,6], [7,8], (9,0))"
b = eval(a)
 
b
Out[11]: ([1, 2], [3, 4], [5, 6], [7, 8], (9, 0))

eval 函数就是实现list、dict、tuple与 str 之间的转化
str 函数把 list,dict,tuple 转为为 字符串
# 字符串转换成列表
a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]"
print(type(a))
b = eval(a)
print(b)

# 字符串转换成字典
a = "{1: 'a', 2: 'b'}"
print(type(a))
b = eval(a)
print(type(b))
print(b)

# 字符串转换成元组
a = "([1,2], [3,4], [5,6], [7,8], (9,0))"
print(type(a))
b=eval(a)
print(type(b))
print(b)

上面简单演示的是eval在字符串对象和list、dictinoary、tuple对象之间的转换作用。

不可谓不强大!

BUT!强大的函数有代价。安全性是其最大的缺点。

想一想这种使用环境:需要用户输入一个表达式,并求值。

如果用户恶意输入,例如:__import__('os').system('dir')
那么 eval() 之后,你会发现,当前目录文件都会展现在用户前面。

eval(__import__('os').system('dir'))

那么继续输入:open('文件名').read()
代码都给人看了。获取完毕,一条删除命令,文件消失。哭吧!

众所周知:

eval()的确是一个很便捷的工具,但是便捷使用不当的同时也会造成严重的安全问题,不少的文章和博客都对eval()的安全性进行了相关的分析,在这里我就不多说了。

怎么避免安全问题?
1、自行写检查函数;
2、使用 ast.literal_eval:自行查看DOCUMENT:https://docs.python.org/2/library/ast.html
3、更多好文:Restricted "safe" eval(Python recipe):http://code.activestate.com/recipes/496746-restricted-safe-/

猜你喜欢

转载自blog.csdn.net/freeking101/article/details/84794313