Python中eval與exec的使用及區別

最近開發中用到了eval()與exec()這兩個函數,不知道在哪一種場景下用哪一個函數,因此就翻了下Python的文檔。這裏就來簡單說一下這兩個函數的區別
1.eval函數
函數的做用:
計算指定表達式的值。也就是說它要執行的Python代碼只能是單個運算表達式(注意eval不支持任意形式的賦值操做),而不能是複雜的代碼邏輯,這一點和lambda表達式比較類似。
函數定義:
eval(expression, globals=None, locals=None)
參數說明:
expression:必選參數,能夠是字符串,也能夠是一個任意的code對象實例(能夠經過compile函數建立)。若是它是一個字符串,它會被看成一個(使用globals和locals參數做爲全局和本地命名空間的)Python表達式進行分析和解釋。
globals:可選參數,表示全局命名空間(存放全局變量),若是被提供,則必須是一個字典對象。
locals:可選參數,表示當前局部命名空間(存放局部變量),若是被提供,能夠是任何映射對象。若是該參數被忽略,那麼它將會取與globals相同的值。
若是globals與locals都被忽略,那麼它們將取eval()函數被調用環境下的全局命名空間和局部命名空間。
返回值:
若是expression是一個code對象,且建立該code對象時,compile函數的mode參數是'exec',那麼eval()函數的返回值是None;
不然,若是expression是一個輸出語句,如print(),則eval()返回結果爲None;
不然,expression表達式的結果就是eval()函數的返回值;
實例:
x = 10
def func():
  y = 20
  a = eval('x + y')
  print('a: ', a)
  b = eval('x + y', {'x': 1, 'y': 2})
  print('b: ', b)
  c = eval('x + y', {'x': 1, 'y': 2}, {'y': 3, 'z': 4})
  print('c: ', c)
  d = eval('print(x, y)')
  print('d: ', d)
func()
輸出結果:
對於變量a,eval函數的globals和locals參數都被忽略了,所以變量x和變量y都取得的是eval函數被調用環境下的做用域中的變量值,即:x = 10, y = 20,a = x + y = 30
對於變量b,eval函數只提供了globals參數而忽略了locals參數,所以locals會取globals參數的值,即:x = 1, y = 2,b = x + y = 3
對於變量c,eval函數的globals參數和locals都被提供了,那麼eval函數會先從所有做用域globals中找到變量x, 從局部做用域locals中找到變量y,即:x = 1, y = 3, c = x + y = 4
對於變量d,由於print()函數不是一個計算表達式,沒有計算結果,所以返回值爲None
2.exec函數
函數的做用:
動態執行Python代碼。也就是說exec能夠執行復雜的Python代碼,而不像eval函數那麼樣只能計算一個表達式的值。
函數定義:
exec(object[, globals[, locals]])
參數說明:
object:必選參數,表示須要被指定的Python代碼。它必須是字符串或code對象。若是object是一個字符串,該字符串會先被解析爲一組Python語句,而後在執行(除非發生語法錯誤)。若是object是一個code對象,那麼它只是被簡單的執行。
globals:可選參數,同eval函數
locals:可選參數,同eval函數
返回值:
exec函數的返回值永遠爲None.
須要說明的是在Python 2中exec不是函數,而是一個內置語句(statement),可是Python 2中有一個execfile()函數。能夠理解爲Python 3把exec這個statement和execfile()函數的功可以整合到一個新的exec()函數中去了。
Eval()函數與exec函數的區別
eval()函數只能計算單個表達式的值,而exec()函數能夠動態運行代碼段。
eval()函數能夠有返回值,而exec()函數返回值永遠爲None。
實例1:
咱們把實例1中的eval函數換成exec函數試試:
x = 10
def func():
  y = 20
  a = exec('x + y')
  print('a: ', a)
  b = exec('x + y', {'x': 1, 'y': 2})
  print('b: ', b)
  c = exec('x + y', {'x': 1, 'y': 2}, {'y': 3, 'z': 4})
  print('c: ', c)
  d = exec('print(x, y)')
  print('d: ', d)
func()
輸出結果:
a:  None
b:  None
c:  None
10 20
d:  None
由於咱們說過了,exec函數的返回值永遠爲None。
實例2:
x = 10
expr = """
z = 30
sum = x + y + z
print(sum)
"""
def func():
  y = 20
  exec(expr)
  exec(expr, {'x': 1, 'y': 2})
  exec(expr, {'x': 1, 'y': 2}, {'y': 3, 'z': 4})
func()
輸出結果:
60
33
34
對輸出結果的解釋:
前兩個輸出跟上面解釋的eval函數執行過程同樣,不作過多解釋。關於最後一個數字34,咱們能夠看出是:x = 1, y = 3是沒有疑問的。關於z爲何仍是30而不是4,這其實也很簡單,咱們只須要在理一下代碼執行過程就能夠了,其執行過程至關於:
x = 1
y = 2
def func():
  y = 3
  z = 4
  z = 30
  sum = x + y + z
  print(sum)
func()express

相關文章
相關標籤/搜索