exec() 方法執行動態創建的程序,該程序可以是字符串或代碼對象。
exec() 的語法:
exec(object, globals, locals)
參數:
exec() 采用三個參數:
- object- 字符串或代碼對象
- globals(可選) - 字典
- locals(可選)- 一個映射對象。字典是 Python 中標準且常用的映射類型。
globals和locals的使用將在本文後麵討論。
返回:
exec() 不返回任何值,它返回 None 。
示例 1:exec() 如何工作?
program = 'a = 5\nb=10\nprint("Sum =", a+b)'
exec(program)
輸出
Sum = 15
這裏,字符串對象program 被傳遞給執行程序的exec()。在這種情況下,globals 和locals 被省略。
示例 2:允許用戶提供輸入
program = input('Enter a program:')
exec(program)
輸出
Enter a program: [print(item) for item in [1, 2, 3]] 1 2 3
如果您想從允許多行代碼的用戶那裏獲取 Python 代碼(使用 '\n' ),您可以在使用 exec() 之前使用 compile() 方法。
了解更多關於compile() method in Python 的信息。
使用exec()時要小心
考慮一種情況,您正在使用 Unix 係統(macOS、Linux 等)並且您已導入 os 模塊。 os 模塊提供了一種可移植的方式來使用操作係統函數,例如讀取或寫入文件。
如果您允許用戶使用 exec(input()) 輸入值,則用戶可以使用命令 os.system('rm -rf *') 發出命令來更改文件甚至刪除所有文件。
如果您在代碼中使用exec(input()),最好檢查用戶可以使用哪些變量和方法。您可以使用 dir() method 查看哪些變量和方法可用。
from math import *
exec('print(dir())')
輸出
['In', 'Out', '_', '__', '___', '__builtin__', '__builtins__', '__name__', '_dh', '_i', '_i1', '_i2', '_ih', '_ii', '_iii', '_oh', '_sh', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exit', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'get_ipython', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'quit', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']
限製 exec() 中可用方法和變量的使用
通常情況下,exec() 中使用的所有可用方法和變量可能都不需要,甚至可能存在安全漏洞。您可以通過將可選的 globals 和 locals 參數(字典)傳遞給 exec() 方法來限製這些變量和方法的使用。
1. globals 和 locals 參數都省略
如果兩個參數都被省略(如我們前麵的示例中所示),則預期由exec() 執行的代碼將在當前範圍內執行。您可以使用以下代碼檢查可用的變量和方法:
exec('print(dir())')
2.傳遞globals參數; locals 參數被省略
globals 和locals parameters(字典)分別用於全局變量和局部變量。如果省略locals 字典,則默認為globals 字典。意思是,globals 將用於全局和局部變量。
注意:您可以使用 Python 檢查當前的全局和本地字典globals和locals內置方法分別。
3. 將空字典作為全局參數傳遞
from math import *
exec('print(dir())', {})
# This code will raise an exception
# exec('print(sqrt(9))', {})
如果您將空字典作為 globals 傳遞,則隻有 __builtins__ 可用於 object(exec() 的第一個參數)。即使我們在上麵的程序中導入了數學模塊,嘗試訪問 math module 提供的任何函數都會引發異常。
輸出
['__builtins__']
使某些方法可用
from math import *
exec('print(dir())', {'sqrt': sqrt, 'pow': pow})
# object can have sqrt() module
exec('print(sqrt(9))', {'sqrt': sqrt, 'pow': pow})
在這裏,exec() 執行的代碼也可以具有 sqrt() 和 pow() 方法以及 __builtins__ 。
可以根據您的意願更改方法的名稱。
from math import *
exec('print(dir())', {'squareRoot': sqrt, 'pow': pow})
# object can have squareRoot() module
exec('print(squareRoot(9))', {'squareRoot': sqrt, 'pow': pow})
在上述程序中,squareRoot() 計算平方根(類似於 sqrt() 的函數)。但是,嘗試使用 sqrt() 會引發異常。
限製內置s的使用
您可以通過將值 None 賦予 globals 字典中的 '__builtins__' 來限製 __builtins__ 的使用。
exec(object, {'__builtins__': None})
4. 傳遞全局和局部字典
您可以通過傳遞locals 字典使所需的函數和變量可供使用。例如:
from math import *
globalsParameter = {'__builtins__' : None}
localsParameter = {'print': print, 'dir': dir}
exec('print(dir())', globalsParameter, localsParameter)
輸出
['dir', 'print']
這裏隻有兩個內置方法print()和dir()可以通過exec()方法執行。
請務必注意,exec() 執行代碼並且不返回任何值(返回 None )。因此,您不能在函數定義之外使用 return 和 yield 語句。
相關用法
- Python exec()用法及代碼示例
- Python math expm1()用法及代碼示例
- Python exponential轉float用法及代碼示例
- Python expandtabs()用法及代碼示例
- Python math exp()用法及代碼示例
- Python numpy matrix eye()用法及代碼示例
- Python enchant.request_dict()用法及代碼示例
- Python eval()用法及代碼示例
- Python enum.IntEnum用法及代碼示例
- Python enchant.get_enchant_version()用法及代碼示例
- Python emoji轉text用法及代碼示例
- Python enchant.request_pwl_dict()用法及代碼示例
- Python enchant.Dict()用法及代碼示例
- Python enum.auto()用法及代碼示例
- Python enchant.list_languages()用法及代碼示例
- Python Wand evaluate()用法及代碼示例
- Python enumerate()用法及代碼示例
- Python enchant.DictWithPWL()用法及代碼示例
- Python PIL eval()用法及代碼示例
- Python enchant.dict_exists()用法及代碼示例
注:本文由純淨天空篩選整理自 Python exec()。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。
