exec() เป็น Built-in Function ที่ Execute Python Code จาก String หรือ Code Object แตกต่างจาก eval() ที่ประเมิน Expression (คืนค่า) exec() รัน Statements (Assignment, Loops, Function Definitions, etc.) และคืนค่า None เสมอ
ไวยากรณ์
exec(source, globals=None, locals=None)
source: String หรือ Code Objectglobals: Global Namespace (Dict)locals: Local Namespace (Dict)
ตัวอย่างพื้นฐาน
1. Execute Simple Statement
code = 'x = 10\ny = 20\nprint(f"x + y = {x + y}")'
exec(code)
# Output: x + y = 30
2. Multi-line String (Triple Quotes)
code = """
numbers = [11, 33, 55, 39, 55, 75, 37, 21, 23, 41, 13]
for num in numbers:
if num % 2 == 0:
print('Found even number:', num)
break
else:
print('No even number found')
"""
exec(code)
# Output: No even number found
3. Dynamic Function Definition
func_code = """
def greet(name):
return f'Hello, {name}!'
def add(a, b):
return a + b
"""
exec(func_code)
# ฟังก์ชันพร้อมใช้งานใน Global Scope
print(greet("World")) # Hello, World!
print(add(5, 3)) # 8
Namespace Control: Globals และ Locals
1. Default Behavior (ใช้ Current Scope)
x = 100
exec('x = 200') # แก้ไข x ใน Global Scope
print(x) # 200
2. Isolated Namespace (แนะนำสำหรับ Security)
# สร้าง Namespace ใหม่
custom_globals = {}
custom_locals = {}
code = """
x = 10
y = 20
result = x + y
"""
exec(code, custom_globals, custom_locals)
print(custom_locals['result']) # 30
print('x' in globals()) # False (ไม่ปนเปื้อน Global Scope)
3. Restricted Built-ins (Security)
# จำกัด Built-ins
restricted_globals = {"__builtins__": {}}
restricted_locals = {"allowed_func": len, "data": [1,2,3]}
code = "result = allowed_func(data)"
exec(code, restricted_globals, restricted_locals)
print(restricted_locals['result']) # 3
# พยายามเข้าถึงอันตราย
try:
exec("__import__('os').system('ls')", restricted_globals, restricted_locals)
except NameError:
print("Blocked!")
⚠️ Security Warning (สำคัญมาก)
exec() อันตรายเท่า eval() หรือมากกว่า เพราะรัน Statements ได้ทุกอย่าง:
- ลบไฟล์:
exec("import os; os.remove('important.txt')") - อ่านไฟล์:
exec("print(open('/etc/passwd').read())") - Network Access, Process Spawning, etc.
Best Practices สำหรับการใช้งานปลอดภัย
1. ไม่ใช้กับ User Input โดยตรง
# ❌ อันตราย
user_code = input("Enter code: ")
exec(user_code)
# ✅ ปลอดภัยกว่า: ใช้ Allowlist
allowed_commands = {
'print': print,
'len': len,
'sum': sum,
}
user_input = input("Enter expression: ")
# Parse และ Validate ก่อน Exec
2. ใช้ Compile() ก่อน (Optional)
code_str = "x = 1\ny = 2\nprint(x+y)" # Compile First (Syntax Check) compiled_code = compile(code_str, '', 'exec') # Execute Compiled Code exec(compiled_code, {}, {})
3. Sandboxing Libraries
RestrictedPython- Restricted Execution EnvironmentPyPy Sandbox- Sandboxed PyPyDocker/Containers- OS-level Isolation
กรณีใช้งานที่เหมาะสม (Legitimate Use Cases)
- Dynamic Plugin/Extension System (Trusted Sources)
- Code Generation Tools (Template -> Code)
- Interactive Python Shells / Notebooks
- Configuration as Code (กับ Validation)
- Testing Frameworks (Dynamic Test Generation)
สรุป
exec()รัน Statements,eval()ประเมิน Expressions- คืนค่า
Noneเสมอ - Security Risk สูงมาก - ไม่ใช้กับ Untrusted Input
- ใช้ Namespace Isolation (
globals,locals) และ Restrict Built-ins - พิจารณาทางเลือก:
importlib,ast.literal_eval,simpleeval, Plugin Architectures