Trình trang trí Python cho các biến

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 wrapper
5 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 wrapper
5 nhận một hàm làm tham số

def wrapper[]:

    print["***************************"]
    fun[]
    print["***************************"]

return wrapper

def wrapper[]:

    print["***************************"]
    fun[]
    print["***************************"]

return wrapper
7 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í

Quảng cáo
enc = enclose[myfun]
enc[]

def wrapper[]:

    print["***************************"]
    fun[]
    print["***************************"]

return wrapper
8 được truyền cho hàm
def wrapper[]:

    print["***************************"]
    fun[]
    print["***************************"]

return wrapper
5, trong đó nó được mở rộng. Hàm bao bọc được trả về và được gọi

def wrapper[]:

    print["***************************"]
    fun[]
    print["***************************"]

return wrapper
0

Đâ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 wrapper
2

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áo
def wrapper[]:

    print["***************************"]
    fun[]
    print["***************************"]

return wrapper
3

Trong ví dụ mã này, hàm thông thường nhận một đối số

def wrapper[]:

    print["***************************"]
    fun[]
    print["***************************"]

return wrapper
4

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 wrapper
6

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áo
def 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 wrapper
8] đượ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 wrapper
0

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 wrapper
1

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 wrapper
2

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 wrapper
3

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 wrapper
01

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 wrapper
02 được sử dụng để xác định các tuyến đường

Quảng cáo
def wrapper[]:

    print["***************************"]
    fun[]
    print["***************************"]

return wrapper
4

Trong ví dụ, hàm

def wrapper[]:

    print["***************************"]
    fun[]
    print["***************************"]

return wrapper
03 đượ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 wrapper
02 của Flask

Bạn có thể trang trí một biến trong Python không?

Không, cú pháp trang trí chỉ hợp lệ trên các hàm và lớp . Các bộ trang trí tồn tại bởi vì bạn không thể bọc một khai báo hàm hoặc lớp trong một lời gọi hàm; .

Người trang trí có thể lấy đối số Python không?

Các đối số của trình trang trí có thể truy cập được đối với trình trang trí bên trong thông qua một bao đóng , chính xác như cách hàm bên trong wrap[] có thể truy cập f. Và vì các bao đóng mở rộng đến tất cả các cấp độ của các hàm bên trong, nên arg cũng có thể truy cập được từ bên trong wrap[] nếu cần.

Hàm được trang trí có thể truy cập các biến của trình trang trí không?

Ai đó đã hỏi liệu điều này có thể được áp dụng cho các phương thức của một lớp không. Câu trả lời là " ", nhưng bạn phải tham chiếu phương thức thông qua chính lớp đó hoặc thể hiện của nó được truyền dưới dạng đối số self. Cả hai kỹ thuật được hiển thị dưới đây.

Trình trang trí Python tốt cho việc gì?

Bạn sẽ sử dụng trình trang trí khi bạn cần thay đổi hành vi của một hàm mà không cần sửa đổi chính hàm đó . Một vài ví dụ điển hình là khi bạn muốn thêm ghi nhật ký, kiểm tra hiệu suất, thực hiện lưu vào bộ nhớ đệm, xác minh quyền, v.v. Bạn cũng có thể sử dụng một mã khi cần chạy cùng một mã trên nhiều chức năng.

Chủ Đề