Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

ฟังก์ชัน eval() ใน Python: การใช้งานและข้อควรระวังด้านความปลอดภัย

eval() ใช้ parse และ execute string เป็น Python expression ภายในโปรแกรม ให้ความยืดหยุ่นแต่มี ความเสี่ยงด้านความปลอดภัยสูง

ไวยากรณ์

eval(expression, globals=None, locals=None)
พารามิเตอร์ คำอธิบาย
expressionString ที่เป็น Python expression (required)
globalsDict สำหรับ global namespace (optional)
localsDict สำหรับ 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)