Python eval ()


Cú pháp eval ()

Cú pháp của eval() Là:

eval(expression, globals=None, locals=None)

eval () Tham số

Các eval() hàm nhận ba tham số:

  • cách biểu lộ – chuỗi được phân tích cú pháp và đánh giá như một biểu thức Python
  • quả cầu (tùy chọn) – từ điển
  • người dân địa phương (tùy chọn) – một đối tượng ánh xạ. Từ điển là loại ánh xạ tiêu chuẩn và được sử dụng phổ biến trong Python.

Việc sử dụng quả cầungười dân địa phương sẽ được thảo luận sau trong bài viết này.


eval () Giá trị trả lại

Các eval() phương thức trả về kết quả được đánh giá từ cách biểu lộ.


Ví dụ 1: Cách eval () hoạt động trong Python

x = 1

print(eval('x + 1'))

Đầu ra

2

Đây, eval() hàm đánh giá biểu thức x + 1print được sử dụng để hiển thị giá trị này.


Ví dụ 2: Ví dụ thực tế để chứng minh việc sử dụng eval ()

# Perimeter of Square
def calculatePerimeter(l):
    return 4*l

# Area of Square
def calculateArea(l):
    return l*l

expression = input("Type a function: ")

for l in range(1, 5):
    if (expression == 'calculatePerimeter(l)'):

print("If length is ", l, ", Perimeter = ", eval(expression))

elif (expression == 'calculateArea(l)'):

print("If length is ", l, ", Area = ", eval(expression))

else: print('Wrong Function') break

Đầu ra

Type a function: calculateArea(l)
If length is  1 , Area =  1
If length is  2 , Area =  4
If length is  3 , Area =  9
If length is  4 , Area =  16

Cảnh báo khi sử dụng eval ()

Hãy xem xét tình huống bạn đang sử dụng hệ thống Unix (macOS, Linux, v.v.) và bạn đã nhập os mô-đun. Mô-đun hệ điều hành cung cấp một cách di động để sử dụng các chức năng của hệ điều hành như đọc hoặc ghi vào một tệp.

Nếu bạn cho phép người dùng nhập giá trị bằng eval(input())người dùng có thể ra lệnh để thay đổi tệp hoặc thậm chí xóa tất cả các tệp bằng lệnh: os.system('rm -rf *').


Nếu bạn đang sử dụng eval(input()) trong mã của bạn, bạn nên kiểm tra các biến và phương pháp mà người dùng có thể sử dụng. Bạn có thể xem các biến và phương thức nào có sẵn bằng cách sử dụng phương thức dir ().

from math import *

print(eval('dir()'))

Đầu ra

['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'os', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']

Hạn chế việc sử dụng các phương thức và biến có sẵn trong eval ()

Thường xuyên hơn không, tất cả các phương pháp và biến có sẵn được sử dụng trong cách biểu lộ (tham số đầu tiên để eval()) có thể không cần thiết, hoặc thậm chí có thể có lỗ hổng bảo mật. Bạn có thể cần phải hạn chế việc sử dụng các phương pháp và biến này cho eval(). Bạn có thể làm như vậy bằng cách chuyển tùy chọn quả cầungười dân địa phương tham số (từ điển) cho eval() chức năng.

1. Khi cả tham số hình cầu và địa phương bị bỏ qua

Nếu cả hai tham số bị bỏ qua (như trong các ví dụ trước đó của chúng tôi), cách biểu lộ được thực thi trong phạm vi hiện tại. Bạn có thể kiểm tra các biến và phương pháp có sẵn bằng cách sử dụng mã sau:

print(eval('dir()')

2. Truyền tham số global; tham số địa phương bị bỏ qua

Các quả cầungười dân địa phương tham số (từ điển) được sử dụng cho các biến cục bộ và toàn cục. Nếu người dân địa phương từ điển bị bỏ qua, nó mặc định là quả cầu từ điển. Nghĩa, quả cầu sẽ được sử dụng cho cả biến toàn cục và biến cục bộ.

Ghi chú: Bạn có thể kiểm tra từ điển toàn cầu và cục bộ hiện tại bằng Python bằng cách sử dụng các phương thức tích hợp sẵn tương ứng là perfals () và local ().


Ví dụ 3: Truyền từ điển trống dưới dạng tham số toàn cầu

from math import *

print(eval('dir()', {}))

# The code will raise an exception

print(eval('sqrt(25)', {}))

Đầu ra

['__builtins__']
Traceback (most recent call last):
  File "<string>", line 5, in <module>
    print(eval('sqrt(25)', {}))
  File "<string>", line 1, in <module>
NameError: name 'sqrt' is not defined

Nếu bạn chuyển một từ điển trống là quả cầuchỉ __builtins__ có sẵn cho expression (tham số đầu tiên cho eval()).

Mặc dù chúng tôi đã nhập math mô-đun trong chương trình trên, cách biểu lộ không thể truy cập bất kỳ chức năng nào được cung cấp bởi mô-đun toán học.


Ví dụ 4: Cung cấp một số phương pháp nhất định

from math import *

print(eval('dir()', {'sqrt': sqrt, 'pow': pow}))

Đầu ra

['__builtins__', 'pow', 'sqrt']

Ở đây, biểu thức chỉ có thể sử dụng sqrt()pow() phương pháp cùng với __builtins__.

Cũng có thể thay đổi tên của phương thức có sẵn cho cách biểu lộ như mong muốn của bạn:

from math import *
names = {'square_root': sqrt, 'power': pow}

print(eval('dir()', names))

# Using square_root in Expression

print(eval('square_root(9)', names))

Đầu ra

['__builtins__', 'power', 'square_root']
3.0

Trong chương trình trên, square_root() tính căn bậc hai bằng cách sử dụng sqrt(). Tuy nhiên, cố gắng sử dụng sqrt() trực tiếp sẽ đưa ra một lỗi.


Ví dụ 5: Hạn chế việc sử dụng cài sẵn

Bạn có thể hạn chế việc sử dụng __builtins__ bên trong cách biểu lộ như sau:

eval(expression, {'__builtins__': None})

3. Vượt qua cả từ điển toàn cầu và địa phương

Bạn có thể cung cấp các hàm và biến cần thiết để sử dụng bằng cách chuyển người dân địa phương từ điển. Ví dụ:

from math import *

a = 169

print(eval('sqrt(a)', {'__builtins__': None}, {'a': a, 'sqrt': sqrt}))

Đầu ra

13.0

Trong chương trình này, cách biểu lộ có thể có sqrt() phương pháp và biến Một chỉ một. Tất cả các phương pháp và biến khác không có sẵn.


Hạn chế sử dụng eval() bằng cách đi qua quả cầungười dân địa phương từ điển sẽ làm cho mã của bạn an toàn đặc biệt khi bạn đang sử dụng đầu vào do người dùng cung cấp cho eval() phương pháp.

Ghi chú: Thỉnh thoảng, eval() không an toàn ngay cả với các tên hạn chế. Khi một đối tượng và các phương thức của nó được làm cho có thể truy cập được, hầu hết mọi thứ đều có thể được thực hiện. Cách an toàn duy nhất là xác thực đầu vào của người dùng.


Trả lời