python eval()python
eval(expression, globals= None, locals= None)express
--官方文檔中的解釋:編程
將字符串str當成有效的表達式子來求值並返回計算結果。安全
globals(全局)和locals(局部)參數是可選的,若是提供了globals參數,那麼它必須是dictionary類型;編程語言
若是提供了locals參數,那麼它能夠是任意的map對象。函數
python查找變量的順序:局部--> 全局--> 內置spa
三個參數的使用:code
一、在前兩個參數省略的狀況下,eval在當前的做用域執行:對象
a=10; print(eval("a+1"))
執行結果爲:11blog
在這種狀況下,後兩個參數省略了,因此eval中的a是前面的10。對於eval,它會將第一個expression字符串參數的引號去掉,而後對引號中的式子進行解析和計算。
二、在globals指定的狀況下:
a=10; g={'a':4} print(eval("a+1",g))
執行結果爲:5
這裏面可能有點繞啊,初學者得理理清楚。在此次的代碼中,咱們在 eval中提供了globals參數,這時候eval的做用域就是g指定的這個字典了,也就是外面的a=10被屏蔽掉了,eval是看不見的,因此使用了a爲4的值。
三、在 locals指定的狀況下 :
a=10 b=20 c=30 g={'a':6,'b':8} t={'b':100,'c':10} print(eval('a+b+c',g,t))
執行的結果爲:116
這裏面就更有點繞人了,這次執行的結果中,a是6,b是100,c是10。咱們首先來看一下,對於a爲6咱們是沒有疑問的,由於在上個例子中已經說了,g會屏蔽程序中的全局變量的,而這裏最主要的是爲何b是100呢?還記得咱們在參數介紹的時候說過,當locals和globals起衝突時,locals是起決定做用的,這在不少編程語言裏都是同樣的,是做用域的覆蓋問題,當前指定的小的做用域會覆蓋之前大的做用域,這能夠理解爲一張小的紙蓋在了一張大的紙上,紙是透明的,上面寫的東西是不透明的,而它們重合的地方就能夠理解成兩個做用域衝突的地方,天然是小的顯現出來了。
eval()的用法:
能夠把list, tuple, dict和string相互轉化。例子:
#字符串轉數字
a = '2'
b = '3'
c = eval(a + b)
c
Out : 5
type(c)
Out : int
#字符串轉列表 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()函數的安全性問題
想想這種使用環境:須要用戶輸入一個表達式,並求值。
若是用戶惡意輸入,例如:
__import__('os').system('dir')
那麼eval()以後,你會發現,當前目錄文件都會展示在用戶前面。
那麼繼續輸入:
open('文件名').read()
代碼都給人看了。獲取完畢,一條刪除命令,文件消失。