1. 程式人生 > 程式設計 >Python使用eval函式執行動態標表達式過程詳解

Python使用eval函式執行動態標表達式過程詳解

英文文件:

eval(expression,globals=None,locals=None)
The arguments are a string and optional globals and locals. If provided,globals must be a dictionary. If provided,localscan be any mapping object.

The expression argument is parsed and evaluated as a Python expression (technically speaking,a condition list) using the globals and locals dictionaries as global and local namespace. If the globals dictionary is present and lacks ‘__builtins__',the current globals are copied into globals before expression is parsed. This means that expressionnormally has full access to the standard builtins module and restricted environments are propagated. If the localsdictionary is omitted it defaults to the globals dictionary. If both dictionaries are omitted,the expression is executed in the environment where eval() is called. The return value is the result of the evaluated expression. Syntax errors are reported as exceptions. Example:

>>> x = 1
>>> eval('x+1')
2

This function can also be used to execute arbitrary code objects (such as those created by compile()). In this case pass a code object instead of a string. If the code object has been compiled with 'exec' as the mode argument,eval()‘s return value will be None.

Hints: dynamic execution of statements is supported by the exec() function. The globals() and locals() functions returns the current global and local dictionary,respectively,which may be useful to pass around for use by eval() or exec().
See ast.literal_eval() for a function that can safely evaluate strings with expressions containing only literals.

  執行動態標表達式求值

說明:  

  1. 執行動態語句,返回語句執行的值。

>>> eval('1+2+3+4')
10

  2. 第一個引數為語句字串,globals引數和locals引數為可選引數,如果提供,globals引數必需是字典,locals引數為mapping物件。

  3. globals引數用來指定程式碼執行時可以使用的全域性變數以及收集程式碼執行後的全域性變數。

>>> g = {'num':2}

>>> eval('num + 2') #num未定義
Traceback (most recent call last):
 File "<pyshell#3>",line 1,in <module>
  eval('num + 2')
 File "<string>",in <module>
NameError: name 'num' is not defined

>>> eval('num + 2',g) #g中有定義num,可執行
4

  4. locals引數用來指定程式碼執行時可以使用的區域性變數以及收集程式碼執行後的區域性變數

>>> g = {'num1':2}
>>> l = {'num2':4}
>>> eval('num1+num2',g,l)
6

  5. 為了保證程式碼成功執行,globals引數字典不包含 __builtins__ 這個 key 時,Python會自動新增一個key為 __builtins__ ,value為builtins模組的引用。如果確實要限制程式碼不使用builtins模組,需要在global新增一個key為__builtins__,value為{}的項即可(很少有人這麼幹吧)。

>>> g = {}
>>> eval('abs(-1)',g)
1
>>> g = {'__builtins__':{}}
>>> eval('abs(-1)',g) #不能使用內建函數了
Traceback (most recent call last):
 File "<pyshell#9>",in <module>
  eval('abs(-1)',g)
 File "<string>",in <module>
NameError: name 'abs' is not defined

  6. 當globals引數不提供是,Python預設使用globals()函式返回的字典去呼叫。當locals引數不提供時,預設使用globals引數去呼叫。

>>> num = 1
>>> eval('num+2')
3

>>> globals() #返回字典中含有num的key
{'__doc__': None,'num': 1,'__package__': None,'__name__': '__main__','__loader__': <class '_frozen_importlib.BuiltinImporter'>,'__spec__': None,'__builtins__': <module 'builtins' (built-in)>}

>>> eval('num+2',{}) #locals引數未提供,locals引數=globals引數
Traceback (most recent call last):
 File "<pyshell#3>",in <module>
  eval('num+2',{})
 File "<string>",in <module>
NameError: name 'num' is not defined

>>> l = locals() 
>>> eval('num+2',{},l) #locals引數含有num的key,能求值
3

>>> locals()
{'__doc__': None,'l': {...},'__builtins__': <module 'builtins' (built-in)>}
>>>

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。