Python中的eval()函數


Python中的eval()函數eval(expression, globals=None, locals=None)  官方文檔中的解釋是,將字符串str當成有效的表達式來求值並返回計算結果。globals和locals參數是可選的,如果提供了globals參數,那么它必須是dictionary類型;如果提供了locals參數,那么它可以是任意的map對象。

example:

a=1
g={'a':20}
eval("a+1",g)

返回21

python是用命名空間來記錄變量的軌跡的,命名空間是一個dictionary,鍵是變量名,值是變量值。

當一行代碼要使用變量 x 的值時,Python 會到所有可用的名字空間去查找變量,按照如下順序:

1)局部名字空間 - 特指當前函數或類的方法。如果函數定義了一個局部變量 x, 或一個參數 x,Python 將使用它,然后停止搜索。

2)全局名字空間 - 特指當前的模塊。如果模塊定義了一個名為 x 的變量,函數或類,Python 將使用它然后停止搜索。

3)內置名字空間 - 對每個模塊都是全局的。作為最后的嘗試,Python 將假設 x 是內置函數或變量。

python的全局名字空間存儲在一個叫globals()的dict對象中;局部名字空間存儲在一個叫locals()的dict對象中。我們可以用print (locals())來查看該函數體內的所有變量名和變量值。

eval()使用原因:

1)在編譯語言里要動態地產生代碼,基本上是不可能的,但動態語言是可以,意味着軟件已經部署到服務器上了,但只要作很少的更改,只好直接修改這部分的代碼,就可立即實現變化,不用整個軟件重新加載。

2)在machin learning里根據用戶使用這個軟件頻率,以及方式,可動態地修改代碼,適應用戶的變化。

 

#test eval() and locals()
x = 1
y = 1
num1 = eval("x+y")
print (num1)

def g():    
    x = 2    
    y = 2  
    num3 = eval("x+y")    
    print (num3)        
    num2 = eval("x+y",globals())   
    #num2 = eval("x+y",globals(),locals())    
    print (num2)
    
g()

print locals()["x"]
print locals()["y"] 
print globals()["x"]
print globals()["y"] 

num1的值是2;num3的值也很好理解,是4;num2的值呢?由於提供了globals()參數,那么首先應當找全局的x和y值,也就是都為1,那么顯而易見,num2的值也是2。如果注釋掉該句,執行下面一句呢?根據第3)點可知,結果為4

locals()對象的值不能修改,globals()對象的值可以修改

#test globals() and locals()

z=0
def f():    
    z = 1    
    print (locals())        
    locals()["z"] = 2    
    print (locals())      
f() 
globals()["z"] = 2
print (z)

可以得出,兩個print (locals())的結果是一樣的,說明沒有修改成功。而print (z)的值是2,說明修改成功了

 

eval有安全性問題,比如用戶惡意輸入就會獲得當前目錄文件

eval("__import__('os').system('dir')")
>>> import os
>>> 'os' in globals()
True
>>> os.system('whoami')
ap\zhail
0

怎么避免安全問題?

1.自行寫檢查函數;

2.使用ast.literal_eval

參考如下網址:

https://docs.python.org/2/library/ast.html

http://python.jobbole.com/82770/

http://code.activestate.com/recipes/496746-restricted-safe-/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM