Các hàm Python là công dân hạng nhất. Điều này có nghĩa là các hàm có trạng thái bình đẳng với các đối tượng khác trong Python. Các chức năng có thể được gán cho các biến, được lưu trữ trong các bộ sưu tập, được tạo và xóa động hoặc được truyền dưới dạng đối số
Hàm lồng nhau, còn được gọi là hàm bên trong, là một hàm được định nghĩa bên trong một hàm khác
Trình trang trí Python mở rộng và sửa đổi hành vi của một cái có thể gọi được mà không sửa đổi chính cái có thể gọi được. Trình trang trí là các chức năng trang trí [hoặc bao bọc] các chức năng khác và thực thi mã trước và sau khi chức năng được bao bọc chạy
Trình trang trí Python thường được sử dụng trong ghi nhật ký, xác thực và ủy quyền, thời gian và bộ nhớ đệm
Ví dụ trang trí Python
Trong ví dụ tiếp theo, chúng tôi tạo một ví dụ trang trí đơn giản
#!/usr/bin/python def enclose[fun]: def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper def myfun[]: print["myfun"] enc = enclose[myfun] enc[]
Hàm
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper5 là một trình trang trí mở rộng chức năng được trang trí bằng cách thêm các ký hiệu ngôi sao vào đầu ra của nó
def enclose[fun]: ...
Hàm
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper5 nhận một hàm làm tham số
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper7 trang trí chức năng được thông qua với các ngôi sao. Hàm bao bọc được trả về
def myfun[]: print["myfun"]
Đây là chức năng thường xuyên được trang trí
enc = enclose[myfun] enc[]
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper8 được truyền cho hàm
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper5, trong đó nó được mở rộng. Hàm bao bọc được trả về và được gọi
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper0
Đây là đầu ra. Trình trang trí thêm các ngôi sao trước và sau đầu ra của hàm thông thường
Python cho phép sử dụng ký hiệu
def myfun[]: print["myfun"]0 để đánh dấu phương thức được trang trí bằng decorator
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper2
Về mặt chức năng, ví dụ này tương đương với ví dụ trước. Chỉ có cú pháp khác nhau được sử dụng
Chức năng trang trí với các tham số
Các ví dụ sau đây cho thấy cách trang trí các hàm nhận tham số
Quảng cáodef wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper3
Trong ví dụ mã này, hàm thông thường nhận một đối số
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper4
Ví dụ này cho thấy cách xử lý số lượng tham số thay đổi bằng cách sử dụng cú pháp
def myfun[]: print["myfun"]1
Chức năng trang trí có thể sửa đổi dữ liệu của chức năng trang trí
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper6
Trình trang trí
def myfun[]: print["myfun"]2 thay đổi văn bản trả về thành chữ hoa
def enclose[fun]: ...0
Bên trong hàm bao bọc, văn bản được sửa đổi và trả về
def enclose[fun]: ...1
Python nhiều trang trí xếp chồng lên nhau
Có thể áp dụng nhiều decorator trên một hàm
def enclose[fun]: ...2
Trong ví dụ, chúng tôi áp dụng hai thẻ HTML trên một văn bản
def enclose[fun]: ...3
Ví dụ về thời gian trang trí Python
Trong ví dụ sau, chúng tôi áp dụng trình trang trí hẹn giờ cho một chức năng
Quảng cáodef enclose[fun]: ...4
Ví dụ tính toán thời gian hàm
def myfun[]: print["myfun"]3 chạy bằng cách sử dụng trình trang trí
def enclose[fun]: ...5
Trước khi chức năng được chạy, chúng tôi nhận được thời gian bắt đầu
def enclose[fun]: ...6
Sau khi chức năng được chạy, chúng tôi nhận được thời gian kết thúc và in sự khác biệt
Trình trang trí funcools @wraps
Sau khi áp dụng hàm trang trí, các thuộc tính
def myfun[]: print["myfun"]4,
def myfun[]: print["myfun"]5 và
def myfun[]: print["myfun"]6 của hàm ban đầu sẽ bị mất. Điều này làm cho việc gỡ lỗi trở nên khó xử. Để khắc phục điều này, chúng ta có thể sử dụng trình trang trí
def myfun[]: print["myfun"]7
def myfun[]: print["myfun"]8
def enclose[fun]: ...7
Trong ví dụ này, chúng tôi áp dụng trình trang trí
def myfun[]: print["myfun"]8 trên hàm bao bọc. Tên và chuỗi tài liệu của hàm ban đầu [
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper8] được giữ nguyên
def enclose[fun]: ...8
Trình trang trí lớp Python
Có thể sử dụng các lớp làm trang trí. Đối với điều này, chúng ta cần triển khai chức năng ma thuật
enc = enclose[myfun] enc[]1
def enclose[fun]: ...9
Trong ví dụ này, chúng tôi sử dụng một trình trang trí lớp để đếm các cuộc gọi của một hàm thông thường
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper0
Chúng tôi gọi hàm
enc = enclose[myfun] enc[]2. Nó có cùng mục đích với trang trí
def myfun[]: print["myfun"]8; . e. nó giữ siêu dữ liệu của chức năng ban đầu [
def myfun[]: print["myfun"]4 hoặc
def myfun[]: print["myfun"]5]. Chúng tôi giữ tham chiếu đến chức năng ban đầu và đặt biến
enc = enclose[myfun] enc[]6
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper1
Chúng tôi tăng biến
enc = enclose[myfun] enc[]6, in một thông báo và gọi hàm ban đầu, truyền cho nó các đối số có thể
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper2
Trình trang trí Python @staticmethod
Python có trình trang trí tích hợp sẵn
enc = enclose[myfun] enc[]8, tạo ra một phương thức tĩnh trong lớp Python. Một phương thức tĩnh thuộc về một lớp và được gọi mà không tạo một thể hiện
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper3
Trong ví dụ này, chúng tôi tạo một phương thức tĩnh
enc = enclose[myfun] enc[]9 bằng cách sử dụng trình trang trí
enc = enclose[myfun] enc[]8. Phương thức được gọi bằng cách chỉ định tên lớp và sử dụng toán tử dấu chấm.
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper01
trang trí bình
Khung Python phổ biến Flask sử dụng trang trí. Chẳng hạn,
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper02 được sử dụng để xác định các tuyến đườngQuảng cáo
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper4
Trong ví dụ, hàm
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper03 được ánh xạ tới trang gốc bằng cách sử dụng trình trang trí
def wrapper[]: print["***************************"] fun[] print["***************************"] return wrapper02 của Flask