Hàm exec() thực thi động code Python từ string hoặc code object. String được parse và kiểm tra syntax error trước khi chạy.
Cú pháp
exec(object, globals=None, locals=None)
1. Truyền string đơn giản
x = 9
exec('print(5 * x)') # 45
2. Truyền code block (multi-line)
code_block = 'x = 3\nif x < 5:\n print(x * x)' exec(code_block) # 9
3. Kiểm soát namespace với globals/locals
Mặc định (không truyền globals/locals):
Có truy cập tất cả biến/hàm trong scope hiện tại + builtins + imported modules.
Truyền globals = {} (chỉ builtins):
from time import *
exec("print(dir())", {}) # Chỉ ['__builtins__']
Cho phép chỉ hàm cụ thể:
from time import *
exec("print(lclt())", {"lclt": localtime}) # Chỉ cho phép localtime
Hạn chế cả builtins (globals={'__builtins__': None}):
from time import *
exec("print(dir())", {"__builtins__": None}, {"gtime": gmtime, "print": print, "dir": dir})
# ['dir', 'gtime', 'print']
Bảng tóm tắt kiểm soát truy cập
| globals | locals | Kết quả |
|---|---|---|
| Không truyền | Không truyền | Full access (scope hiện tại) |
| {} | Không truyền | Chỉ builtins |
| {'func': func} | Không truyền | Builtins + func |
| {'__builtins__': None} | {'func': func} | Chỉ func (không builtins) |
Kết luận
exec() mạnh mẽ cho metaprogramming nhưng nguy hiểm. Luôn hạn chế namespace khi exec code không tin cậy.