Python 中的 exec() 函式


Exec 函式可以動態執行 Python 程式的程式碼。程式碼可以作為字串或物件程式碼傳遞給此函式。物件程式碼按原樣執行,而字串則首先被解析並檢查是否存在任何語法錯誤。如果沒有語法錯誤,則解析後的字串將作為 Python 語句執行。

exec() 函式的語法

exec(object, globals, locals)

其中

  • 物件 − 傳遞給方法的字串或程式碼物件。

  • globals − 可用的全域性方法和變數的字典。

  • locals − 可用的區域性方法和變數的字典。

傳遞字串

在下面的示例中,我們將一行程式碼作為字串傳遞給 exec() 函式。它被解析並執行以給出輸出。

x = 9
exec ('print(5*x)')

輸出

執行以上程式碼將給出以下結果:

45

傳遞程式碼物件

現在我們來看看如何傳遞包含多個程式碼語句的程式碼塊。因為它是一個程式碼物件,所以它會直接執行並給出結果。請注意我們如何使用 \n 和空格來建立一個具有正確縮排的 Python 程式碼塊。

示例

prog_block = 'x = 3 \nif(x < 5): \n print x*x'
exec(prog_block)

輸出

執行以上程式碼將給出以下結果:

9

無全域性和區域性引數

當我們不為全域性和區域性引數傳遞任何值時,我們將根據匯入到程式中的包獲得預設可用的函式。在下面的示例中,我們看到當全域性和區域性引數值都被跳過時,程式碼為我們提供了所有可用的函式。

from time import *
exec("print(dir())")

執行以上程式碼將給出以下結果:

['In', 'Out', '_', '__', '___', '__builtin__', '__builtins__', '__doc__', '__file__', '__name__', 
'__package__', '_dh', '_exit_code', '_i', '_i1', '_i10', '_i11', '_i12', '_i13', '_i14', '_i15',
 '_i16', '_i17', '_i18', '_i19', '_i2', '_i20', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'clock', 
'copysign', 'cos', 'cosh', 'ctime', 'daylight', 'degrees', 'e', 'erf', 'erfc', 'exit', 'exp', 'expm1', 
'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'get_ipython', 'gmtime', 'hypot', 
'isinf', 'isnan', 'ldexp', 'lgamma', 'localtime', 'log', 'log10', 'log1p', 'mktime', 'modf', 'pi', 
'pow', 'prog', 'prog_block', 'quit', 'radians', 'sin', 'sinh', 'sleep', 'sqrt', 'strftime', 'strptime', 
'struct_time', 'tan', 'tanh', 'time', 'timezone', 'trunc', 'tzname', 'x']

使用全域性引數應用限制

我們可以透過傳遞一個空字典作為全域性引數來限制對匯入模組中任何函式的訪問。在這種情況下,結果將僅顯示內建函式,而不會顯示匯入模組中的任何函式。這就是我們如何限制並使函式更安全的方法。

示例

 線上演示

from time import *
exec("print(dir())",{})

輸出

執行以上程式碼將給出以下結果:

['__builtins__']

僅允許選定的函式

接下來,我們看看如何僅將從匯入模組中選擇的特定函式應用於 exec() 方法。在下面的示例中,我們只允許所需的函式作為全域性選項的引數。localtime() 函式是程式中匯入的 time 模組的一部分。示例

 線上演示

from time import *
exec("print lclt()",{"lclt":localtime})

輸出

執行以上程式碼將給出以下結果:

time.struct_time(tm_year=2019, tm_mon=7, tm_mday=19, tm_hour=12, tm_min=33, tm_sec=53, tm_wday=4, tm_yday=200, tm_isdst=0)

傳遞區域性引數

我們還可以透過使用區域性引數並完全排除內建函式來限制對從匯入模組中各種函式的使用。在下面的示例中,我們選擇 None 作為內建全域性引數的值。

示例

 線上演示

from time import *
exec("print(dir())", {"__builtins__" : None}, {"gtime": gmtime, "print": print, "dir": dir})

執行以上程式碼將給出以下結果:

['dir', 'gtime', 'print']

更新於:2019年8月23日

1K+ 次瀏覽

啟動你的職業生涯

透過完成課程獲得認證

開始
廣告