1. Tổng quan

Dưới đây là một số sự thật quan trọng về các hàm trong Python, rất hữu ích để có thể hiểu được về decorator functions – hàm trang trí.

1. Trong Python, chúng ta có thể khai báo một hàm ở bên trong một hàm khác.

2. Trong Python, một hàm có thể được truyền làm tham số cho một hàm khác (và một hàm cũng có thể trả về một hàm khác).

# -----------------------------------------------------------
#Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
#@author cafedevn
#Contact: cafedevn@gmail.com
#Fanpage: https://www.facebook.com/cafedevn
#Instagram: https://instagram.com/cafedevn
#Twitter: https://twitter.com/CafedeVn
#Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
# -----------------------------------------------------------


# A Python program to demonstrate that a function 
# can be defined inside another function and a 
# function can be passed as parameter. 
  
# Adds a welcome message to the string 
def messageWithWelcome(str): 
  
    # Nested function 
    def addWelcome(): 
        return "Welcome to "
  
    # Return concatenation of addWelcome() 
    # and str. 
    return  addWelcome() + str
  
# To get site name to which welcome is added 
def site(site_name): 
    return site_name 
  
print messageWithWelcome(site("Cafedev.vn")) 

Kết quả in ra là:

Welcome to Cafedev.vn

2. Function Decorator – Phần “trang trí” dành cho hàm

Một decorator chính là một hàm mà nhận vào một hàm khác làm tham số duy nhất của nó, rồi lại trả về một hàm. Điều này thật sự hữu dụng trong việc “đóng gói” các chức năng với cùng một đoạn code, để sử dụng lặp đi lặp lại. Ví dụ, đoạn code trên có thể được viết lại như sau.

Chúng ta sử dụng cú pháp @func_name để chỉ định một cái decorator được áp dụng trên một hàm cụ thể.

# -----------------------------------------------------------
#Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
#@author cafedevn
#Contact: cafedevn@gmail.com
#Fanpage: https://www.facebook.com/cafedevn
#Instagram: https://instagram.com/cafedevn
#Twitter: https://twitter.com/CafedeVn
#Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
# -----------------------------------------------------------


# Adds a welcome message to the string 
# returned by fun(). Takes fun() as 
# parameter and returns welcome(). 
def decorate_message(fun): 
  
    # Nested function 
    def addWelcome(site_name): 
        return "Welcome to " + fun(site_name) 
  
    # Decorator returns a function 
    return addWelcome 
  
@decorate_message
def site(site_name): 
    return site_name; 
  
# Driver code 
  
# This call is equivalent to call to 
# decorate_message() with function 
# site("Cafedev") as parameter 
print site("Cafedev.vn") 

Kết quả in ra là:

Welcome to Cafedev.vn

Các Decorators còn hữu dụng trong việc đính kèm dữ liệu (hoặc bổ sung các thuộc tính) cho hàm.


# A Python example to demonstrate that 
# decorators can be useful attach data 
  
# A decorator function to attach 
# data to func 
def attach_data(func): 
       func.data = 3
       return func 
  
@attach_data
def add (x, y): 
       return x + y 
  
# Driver code 
  
# This call is equivalent to attach_data() 
# with add() as parameter 
print(add(2, 3)) 
  
print(add.data) 

Kết quả in ra là:

5
3

Hàm ‘add()’ trả về tổng của x và y (là 2 đối số được truyền vào hàm), nhưng nó lại được đóng gói bởi một decorator function – hàm đã được trang trí, do đó việc gọi hàm add(2, 3) sẽ chỉ đơn giản là cung cấp cho ta tổng của hai số, nhưng sau đó, khi chúng ta gọi add.data thì hàm ‘add’ sẽ được truyền vào làm đối số cho cái decorator function ‘attach_data’, và hàm này sẽ trả về hàm ‘add’ với một thuộc tính ‘data’ được đặt giá trị là 3, rồi in nó ra.

Decorators là một công cụ rất mạnh mẽ giúp loại bỏ các đoạn code dư thừa khi lập trình, trong bài tiếp theo, Decorators trong Python, chúng ta sẽ nói chi tiết hơn về decorator, xin chào và hẹn gặp lại các bạn trong bài sau!

Nguồn và Tài liệu tiếng anh tham khảo:

Tài liệu từ cafedev:

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!