Hàm eval() phân tích và thực thi biểu thức Python được truyền vào dưới dạng chuỗi. Nói cách khác, nó thông dịch một chuỗi như code Python bên trong chương trình.
Cú pháp
eval(expression, globals=None, locals=None)
- expression: Biểu thức Python dưới dạng string
- globals: Dict các biến/hàm toàn cục (tùy chọn)
- locals: Dict các biến/hàm cục bộ (tùy chọn)
Ví dụ cơ bản
# Người dùng nhập biểu thức
user_expr = input("Nhập biểu thức theo biến a: ")
a = int(input("Nhập giá trị a: "))
result = eval(user_expr)
print(f"Kết quả = {result}")
Kết quả mẫu
Nhập biểu thức theo biến a: a*(a-3)+a**2 Nhập giá trị a: 7 Kết quả = 33
Vấn đề bảo mật nghiêm trọng ⚠️
eval() cho phép thực thi code tùy ý. Nếu input từ người dùng không tin cậy (web app, desktop app), kẻ tấn công có thể inject lệnh hệ thống (xóa file, đọc dữ liệu nhạy cảm).
Cách giảm thiểu rủi ro
1. Bỏ qua globals và locals (chỉ scope hiện tại)
eval(user_expr) # Chỉ truy cập biến cục bộ/toàn cục hiện tại
2. Truyền globals rỗng, locals rỗng - chỉ builtins
from time import *
print(eval('dir()', {})) # Chỉ ['__builtins__']
3. Cho phép chỉ một số hàm cụ thể
from time import *
print(eval('dir()', {'sleeptime': sleep, 'Localtime': localtime}))
# ['Localtime', '__builtins__', 'sleeptime']
4. Hạn chế cả globals và locals (an toàn nhất)
from time import *
a = 1445945763
print(eval('gmtime(a)', {'__builtins__': None}, {'a': a, 'gmtime': gmtime}))
# time.struct_time(...)
Kết luận
eval() mạnh nhưng nguy hiểm. Không bao giờ dùng eval() với input không tin cậy. Nếu bắt buộc, hãy hạn chế scope bằng globals/locals. Thay thế an toàn hơn: ast.literal_eval() (chỉ evaluate literal), hoặc parser riêng.