eval在python中是什么意思_如何在Python中使用eval ?
Python中的 eval是什么?
在Python中,我們有許多內置方法,這些方法對于使Python成為所有人的便捷語言至關重要,而eval是其中一種。eval函數的語法如下:
eval(expression, globals, locals)
如上所示,eval函數采用三個參數:expression –需要一個字符串,該字符串將被解析并評估為Python表達式
globals(可選)–一個字典,用于指定可用的全局方法和變量。
locals(可選)-另一個字典,用于指定可用的本地方法和變量。
稍后將在本文中顯示對global(全局變量)s和locals(本地變量)的使用。
eval在Python中做什么?
eval函數解析expression參數并將其評估為python表達式。換句話說,我們可以說這個函數解析了傳遞給它的表達式并在程序中運行python expression(code)。
為了評估基于字符串的表達式,Python的eval函數運行以下步驟:解析表達式
編譯成字節碼
將其評估為Python表達式
返回評估結果
這意味著當我們將任何python表達式作為“字符串”傳遞給eval函數時,它會評估該表達式并將結果返回為整數或浮點數。以下是一些簡單的示例,它們將使您更加清楚。
這是在Python中使用eval將字符串轉換為整數,復數或浮點數的簡單方法:
num =“ 23”
float_num =“ 53.332”
complex_num =“ 2 + 3j”
str1 =“ Not number”
print(eval(num),type(eval(num)))
print(eval(float_num),type( eval(float_num)))
print(eval(complex_num),type(eval(complex_num)))
print(eval(str1),type(eval(str1))) code>
OUTPUT:
23
53.332
(2+3j)
Traceback (most recent call last):
File "main.py", line 8, in
print(eval(str1),type(eval(str1)))
File "", line 1
Not number
^
SyntaxError: unexpected EOF while parsing
如您所見,eval函數能夠識別字符串中的表達式并將其轉換為相應的類型。但是,當我們僅傳遞字符和字母時,它返回了一個錯誤。這應該清楚eval的實際作用。
這里有更多的例子,其中我們不僅僅涉及類型轉換,實際上我們看到了eval函數評估字符串中的表達式。
我們還可以使用eval求解數學表達式:
expr =“(2+(3 * 2))/ 2”
print(eval(expr)) code>
OUTPUT:
4.0
我們甚至可以在字符串中使用變量名,Python還將對它們進行評估,如下所示
num=10
expr="(2+(3*2))/2 + num"
print(eval(expr))
OUTPUT:
14.0
我們還可以在字符串內部使用內置函數,如下所示:
print(eval("sum([8, 16, 34])"))
OUTPUT:
58
為了更好地了解eval函數,讓我們看看如果將表達式用兩個字符串括起來,它將如何響應,如下所示:
#string in another string
expr="'2+3'"
print(eval(expr))
print(eval(eval(expr)))
OUTPUT:
2+3
5
因此,第一個eval函數只是返回字符串中的表達式,但是在另一個eval函數中使用eval時,我們得到了表達式的答案。
如何在python中使用eval ?
在上一節中,我們已經了解了如何使用eval函數,但是在這里,我們將了解eval函數的其他參數如何影響其工作。因此,Python中的eval 還有兩個參數,即viz-globals和locals。
全局變量是當前全局范圍或命名空間中可用的對象。您可以從代碼中的任何位置訪問它們。
在執行時,傳遞給字典中全局變量的所有對象將對eval()可用。請查看以下示例,該示例顯示了如何使用自定義詞典為eval函數提供全局名稱空間:
num1 = 100 # A global variable
print(eval("num1 + 100", {"num1": num1}))
num2 = 200 # Another global variable
print(eval("num1 + num2", {"num1": num1,"num2": num2}))
print(eval("num1 + num2", {"num1": num1}))
OUTPUT:
200
300
Traceback (most recent call last):
File "main.py", line 5, in
print(eval("num1 + num2", {"num1": num1}))
File "", line 1, in
NameError: name 'num2' is not defined
如您在上面的示例中看到的,首先eval只能訪問num1和num2,但是當我從globals字典中刪除num2時,它拋出了一個錯誤,因為它現在無法識別num2。
但是,為什么在我甚至沒有將值傳遞給globals參數的上述示例中都沒有發生這種錯誤?
事實證明,當您在不提供globals參數的情況下調用eval函數時,該函數將使用globals()函數返回的字典作為其全局命名空間來評估表達式。
因此,在上面的示例中,我們可以自由訪問所有變量,因為它們是當前全局范圍中包含的全局變量。
現在,如果將空字典傳遞給全局變量會發生什么,讓我們看看:
a=2
print(eval("sum([2, 2, 2])", {}))
print(eval("sum([a, 2, 2])", {}))
OUTPUT:
6
Traceback (most recent call last):
File "main.py", line 3, in
print(eval("sum([a, 2, 2])", {}))
File "", line 1, in
NameError: name 'a' is not defined
因此,eval函數可以成功識別函數和,但無法識別對象“ a”,因此返回錯誤。
當我們向全局變量提供自定義詞典時,它包含鍵“ __builtins__”的值,但如果不包含該值,則在解析表達式之前,將自動在“ __builtins__”下插入對內置字典的引用。這樣可以確保eval()函數在評估表達式時將完全訪問所有Python的內置名稱。這說明了在上面的示例中,如何通過eval識別函數和。
現在讓我們看看什么是局部變量以及它們如何擴展eval函數的功能。與全局變量不同,局部對象在函數內部聲明,不能在函數外部訪問。
類似地,locals參數采用一個字典,在字典中我們添加了一些對象,而eval()函數將這些對象視為本地對象。請看下面的例子:
print(eval("sum([a, 2, 2])",{}, {"a":2}))
print(a)
OUTPUT:
6
Traceback (most recent call last):
File "main.py", line 2, in
print(a)
NameError: name 'a' is not defined
請注意,要向本地人提供字典,您首先需要向全局人提供字典。不能將關鍵字參數與eval()一起使用
這似乎令人困惑,但是在下面的示例中,我同時使用了globals和locals參數,您將看到它們如何影響結果。
print(eval("abs(-1)"))
#By keeping __builtins__":None,eval will recognise no in-buiilt function
print(eval('abs(-1)',{"__builtins__":None}))
OUTPUT:
1
Traceback (most recent call last):
File "main.py", line 1, in
print(eval('abs(-1)',{"__builtins__":None}))
File "", line 1, in
TypeError: 'NoneType' object is not subscriptable
現在,我們希望該函數在eval函數中起作用,因此將其添加到本地字典中。現在,eval函數可以識別abs函數,而不能識別任何其他函數。
print(eval('abs(-1)',{"__builtins__":None},{"abs":abs}))
OUTPUT:
1
全局變量和局部變量之間的主要實際區別是,如果該密鑰尚不存在,Python會自動將“ __builtins__”鍵插入全局變量。無論是否為全局變量提供自定義詞典,都會發生這種情況。另一方面,如果向本地人提供自定義詞典,則在執行eval函數期間該詞典將保持不變。
評估的局限性
Python中的eval()很有用,但也有重要的安全隱患。eval函數被認為是不安全的,因為它允許您或其他用戶動態執行任意Python代碼。那對我們有什么影響?
假設您正在服務器上運行的應用程序中要求用戶輸入。現在,如果您在輸入上使用eval函數,則用戶可以訪問服務器本身。用戶可以像這樣傳遞一些可疑的代碼:
__ import __('subprocess')。getoutput('rm –rf *')
code>
上面的代碼將刪除應用程序當前目錄中的所有文件,這肯定會影響我們。
因此,最好避免使用eval函數,但是如果仍然要使用eval函數,我們可以借助globals和locals參數來限制其功能。正如我們在上一節中看到的那樣,我們限制eval函數,使其只能使用python的abs函數。
例如,假設我有一個應用程序,可以在給定數字或所有給定數字的總和中找到最小值。像這樣使用eval的最方便方法
print(eval(input()))
#input:sum([1,3,4])
#output:8
#input:min([1,3,4])
#output:1 code>
但是,這是一種不好的編程方式。我們無法控制用戶的輸入內容,因此我們可以利用globals和locals參數,使得eval不能識別sum()和min()以外的函數。這肯定會和上面的代碼做同樣的事情,但是要安全得多。
print(eval(input(),{“ __ builtins __”:None},{“ min”:min,“ sum”:sum})) code>
希望大家可以通過本文了解到Python中的 eval函數,如果您想了解更多有關python案例實操,建議閱讀“Python經典80案例實操”
總結
以上是生活随笔為你收集整理的eval在python中是什么意思_如何在Python中使用eval ?的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: python 画系统关联图_Python
- 下一篇: python 标准化_数据标准化
