CodeGym /Các khóa học /Python SELF VI /Sức mạnh của Decorators

Sức mạnh của Decorators

Python SELF VI
Mức độ , Bài học
Có sẵn

6.1 Decorators cho phương thức của class

Decorators cũng có thể được sử dụng cho phương thức của class. Quan trọng là bạn cần nhớ truyền đúng các tham số self hoặc cls cho phương thức.

Chúng ta chưa đi sâu vào chi tiết về cách hoạt động của các class, nhưng mình muốn các bạn biết rằng decorators có khả năng này.


def log_method_call(func):
    def wrapper(self, *args, **kwargs):
        print(f"Gọi phương thức {func.__name__}")
        return func(self, *args, **kwargs)

    return wrapper
        
class MyClass:
    @log_method_call
    def say_hello(self):
        print("Hello from MyClass!")
        
obj = MyClass()
obj.say_hello()

Giải thích

Decorator (log_method_call): Decorator này nhận phương thức func và trả về một hàm mới wrapper in ra thông điệp trước khi gọi phương thức.

Phương thức class với decorator (say_hello): Phương thức say_hello được bao bọc bởi decorator log_method_call, thêm hành vi bổ sung khi nó được gọi.

Output:


Gọi phương thức say_hello
Hello from MyClass!

6.2 Nhiều Decorators

Bạn có thể sử dụng nhiều decorators cho một hàm, theo kiểu chồng lên nhau. Decorators được áp dụng theo thứ tự ngược với thứ tự khai báo của chúng.


def decorator1(func):
    def wrapper():
        print("Decorator 1")
        func()

    return wrapper
        
def decorator2(func):
    def wrapper():
        print("Decorator 2")
        func()

    return wrapper
        
@decorator1
@decorator2
def say_hello():
    print("Hello!")
        
say_hello()

Giải thích

Decorators (decorator1 và decorator2): Các decorator này thêm thông điệp của chúng trước khi gọi hàm func.

Hàm với decorators (say_hello): Hàm say_hello được bao bọc bởi cả hai decorators. Đầu tiên là decorator2, sau đó là decorator1.

Output:


# Decorator 1
# Decorator 2
Hello!

6.3 Decorators tích hợp

Python cung cấp một số decorators tích hợp cho các nhiệm vụ tiêu chuẩn, chẳng hạn như static methods, class methods và properties.

@staticmethod

Decorator @staticmethod được dùng để tạo ra static method, không yêu cầu instance của class để gọi.


class MyClass:
    @staticmethod
    def static_method():
        print("Đây là static method.")
        
MyClass.static_method()

@classmethod

Decorator @classmethod được dùng để tạo ra class method, nhận class (không phải instance) làm tham số đầu tiên.


class MyClass:
    @classmethod
    def class_method(cls):
        print(f"Đây là class method {cls.__name__}.")
        
MyClass.class_method()

@property

Decorator @property được dùng để tạo ra getters, setters và deleters cho các thuộc tính.


class MyClass:
    def __init__(self, value):
        self.hidden_value = value
        
    @property
    def value(self):
        return self.hidden_value
        
    @value.setter
    def value(self, new_value):
        self.hidden_value = new_value
        
obj = MyClass(10)
print(obj.value)  # Kết quả: 10
obj.value = 20
print(obj.value)  # Kết quả: 20

Đây là các decorators tích hợp, và Python interpreter đảm bảo hoạt động đúng của chúng.

6.4 Ví dụ về sử dụng decorators

Logging

Decorators có thể được sử dụng để ghi lại các lần gọi hàm và phương thức.


def log_call(func):
    def wrapper(*args, **kwargs):
        print(f"Gọi hàm {func.__name__} với tham số {args} và {kwargs}")
        return func(*args, **kwargs)

    return wrapper
        
@log_call
def add(x, y):
    return x + y
        
print(add(2, 3))

Kiểm soát truy cập

Decorators có thể được sử dụng để kiểm soát truy cập vào các hàm và phương thức.


def require_authentication(func):
    def wrapper(*args, **kwargs):
        if not args[0].is_authenticated:
            raise PermissionError("Người dùng không xác thực.")
        return func(*args, **kwargs)
        
    return wrapper
        
class User:
    def __init__(self, is_authenticated):
        self.is_authenticated = is_authenticated
        
    @require_authentication
    def view_profile(self):
        print("Hồ sơ người dùng")
        
user = User(is_authenticated=True)
user.view_profile()  # Gọi thành công
        
user2 = User(is_authenticated=False)
user2.view_profile()  # PermissionError: Người dùng không xác thực.

Caching

Decorators có thể được sử dụng để lưu trữ kết quả của hàm.


def cache(func):
    cached_results = {}

    def wrapper(*args):
        if args in cached_results:
            return cached_results[args]
        result = func(*args)
        cached_results[args] = result
        return result

    return wrapper

@cache
def fib(n):
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)

print(fib(35))
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION