1. 程式人生 > >Python中的exec和eval函式

Python中的exec和eval函式

1、exec

函式exec將字串作為程式碼執行

 exec("print('Hello,world!')")
 Hello,world!

然而,呼叫函式exec時只給它提供一個引數絕非好事。大多數情況下,還應向它傳遞一個名稱空間——用於放置變數的地方;否則程式碼將汙染你的名稱空間,即修改你的變數。例如,假設程式碼使用了名稱sqrt,結果將如何呢?

from math import sqrt
exec('Sqrt = 1', scope)
sqrt(4)

輸出:

TypeError                                 Traceback (most recent call last)
<ipython-input-34-317e033d29d5> in <module>
----> 1 sqrt(4)
TypeError: 'int' object is not callable

既然如此,為何要將字串作為程式碼執行呢?函式exec主要用於動態地建立程式碼字串。如果這種字串來自其他地方(可能是使用者),就幾乎無法確定它將包含什麼內容。因此為了安全起見,要提供一個字典以充當名稱空間。

from math import sqrt
scope = {}
exec('sqrt = 1', scope)
sqrt(4)

輸出:

2.0

如你所見,可能帶來破壞的程式碼並非覆蓋函式sqrt。函式sqrt該怎樣還怎樣,而通過exec執行賦值語句建立的變數位於scope中。
請注意,如果你嘗試將scope打印出來,將發現它包含惡化你多內容,這是因為自動在其中添加了包含所有內建函式和值的字典__builtins__

len(scope)

輸出

2
scope.keys()

輸出

dict_keys(['__builtins__', 'Sqrt'])

2、eval

eval是一個類似於exec的內建函式。exec執行一系列Python語句,而eval計算用字串表示的Python表示式的值,並返回結果(exec什麼都不返回,因為它本身是條語句)。例如,你可使用如下程式碼來建立一個Python計算器:

eval(input("Enter an arithmetic expression: "))

輸出

Enter an arithmetic expression: 10+13**2
179

與exec一樣,也可以向eval提供一個名稱空間,雖然表示式通常不會像語句那樣給變數重新賦值。