Decorator trong Python

Table of Content

Đôi khi, bạn muốn thay đổi chức năng của hàm mà không thay đổi mã của nó. Ví dụ như thêm câu lệnh debug để xem đối số được truyền vào hàm là gì.

Một decorator là một hàm, nhận vào một hàm và trả về một hàm khác.

Tạo một decorator document_it() thực hiện những công việc sau:

  • In tên hàm và giá trị các đối số của nó.
  • Chạy hàm với các đối số này.
  • In kết quả.
  • Trả về hàm đã chỉnh sửa để sử dụng.

Đoạn mã trông như sau:

>>> def document_it(func):
        def new_function(*args, **kwargs):
            print("Running function:", func.__name__)
            print("Positional arguments:", args)
            print("Keyword arguments:", kwargs)
            result = func(*args, **kwargs)
            print("Result:", result)
            return result
        return new_function

Có hai cách sử dụng decorator vừa tạo. Bạn có thể chạy decorator bằng tay:

>>> def add_ints(a, b):
        return a + b
>>> add_ints(3, 5)
8
>>> cooler_add_ints = document_it(add_ints)
>>> cooler_add_ints(3, 5)
Running function: add_ints
Positional arguments: (3, 5)
Keyword arguments: {}
Result: 8
8

Cách thứ hai là đặt @tên_decorator trước hàm bạn muốn thay đổi chức năng:

>>> @document_it
    def add_ints(a, b):
        return a + b
>>> add_ints(3, 5)
Running function: add_ints
Positional arguments: (3, 5)
Keyword arguments: {}
Result: 8
8

Bạn có thể áp dụng nhiều decorator cho một hàm. Cùng viết một decorator khác gọi là square_it() giúp bình phương kết quả:

>>> def square_it(func):
        def new_function(*args, **kwargs):
            result = func(*args, **kwargs)
            return result * result
        return new_function 

Các decorator chạy từ decorator ở vị trí thấp nhất đến decorator ở vị trí cao nhất:

>>> @document_it
@square_it
def add_ints(a, b):
    return a + b

>>> add_ints(3, 5)
Running function: new_function
Positional arguments: (3, 5)
Keyword arguments: {}
Result: 64
64
>>> @square_it
@document_it
def add_ints(a, b):
    return a + b

>>> add_ints(3, 5)
Running function: add_ints
Positional arguments: (3, 5)
Keyword arguments: {}
Result: 8
64

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *