eval() ใช้ parse และ execute string เป็น Python expression ภายในโปรแกรม ให้ความยืดหยุ่นแต่มี ความเสี่ยงด้านความปลอดภัยสูง
ไวยากรณ์
eval(expression, globals=None, locals=None)
| พารามิเตอร์ | คำอธิบาย |
|---|---|
expression | String ที่เป็น Python expression (required) |
globals | Dict สำหรับ global namespace (optional) |
locals | Dict สำหรับ local namespace (optional) |
ตัวอย่างพื้นฐาน
str1 = 'Hello'
print(eval('str1 == "Hello"')) # True
print(eval('str1 + ", Python"')) # Hello, Python
ใช้กับ User Input (คำนวณคณิตศาสตร์)
from math import *
for _ in range(2):
func = input("Enter Math Function to Evaluate:\n")
try:
print(eval(func))
except Exception as ex:
print(ex)
break
print('Done')
ตัวอย่างรัน:
Enter Math Function to Evaluate: abs(-42) 42 Enter Math Function to Evaluate: max(12, 3, 4, 2, 17) 17 Done
ควบคุมสิทธิ์ด้วย globals และ locals
ดู symbol table ปัจจุบัน
from math import *
def square_root(n):
return sqrt(n)
print('Global symbols:', globals())
print('Local symbols:', locals())
print('Names in scope:', dir())
จำกัด built-ins (ปลอดภัยกว่า)
>>> eval('dir()', {})
['__builtins__'] # มีแค่ __builtins__
อนุญาตเฉพาะฟังก์ชันบางตัว
from math import *
for _ in range(3):
func = input("Enter Math Function (allowed: abs, pow):\n")
try:
# สร้าง namespace ที่มีแค่ abs และ pow
safe_dict = {'absolute': abs, 'pow': pow}
print(eval(func, safe_dict))
except Exception as ex:
print(ex)
break
print('Done')
ผลลัพธ์:
Enter Math Function (allowed: abs, pow): abs(-74) 74 Enter Math Function (allowed: abs, pow): pow(2, 7) 128.0 Enter Math Function (allowed: abs, pow): sqrt(47) name 'sqrt' is not defined # error เพราะไม่อนุญาต Done
⚠️ ข้อควรระวัง: ความปลอดภัย (Security Risks)
⚠️ ไม่ควรใช้ eval() กับ input จากผู้ใช้โดยตรงใน Production!
- ผู้ใช้สามารถรันโค้ด bất kỳได้:
__import__('os').system('rm -rf /') - เข้าถึงไฟล์ระบบ, network, database ได้
- หลีกเลี่ยงได้ด้วย
ast.literal_eval()(ปลอดภkais)
ทางเลือกที่ปลอดภัยกว่า: ast.literal_eval()
ขvaluate เฉพาะ literals (strings, numbers, tuples, lists, dicts, booleans, None) — ไม่รันโค้ด
import ast
# ปลอดภัย
print(ast.literal_eval("[1, 2, 3]")) # [1, 2, 3]
print(ast.literal_eval("{'a': 1}")) # {'a': 1}
print(ast.literal_eval("'hello'")) # hello
# ไม่ทำงาน (ปลอดภัย)
# ast.literal_eval("__import__('os').system('ls')") # ValueError
# ast.literal_eval("open('file.txt').read()") # ValueError
เมื่อไหร่ควรใช้ eval()?
- คำนวณ mathematical expressions จาก trusted source
- Dynamic code generation ใน controlled environment
- REPL / Interactive shells
- ไม่ใช้กับ user input จากภายนอกโดยไม่ sanitize
สรุป
| ฟังก์ชัน | ความปลอดภัย | ใช้กับ |
|---|---|---|
eval() | ⚠️ อันตราย | Expressions ทั้งหมด (รวม function calls) |
ast.literal_eval() | ✅ ปลอดภัย | Literals เท่านั้น (list, dict, tuple, str, num) |
exec() | ⚠️ อันตรายมาก | Statements (หลายบรรทัด, loops, assignments) |