Open In App

How To Use Self With Decorator?

Last Updated : 06 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Python decorators are a powerful and flexible feature that allows you to modify or extend the behavior of functions or methods. When working with methods in classes, it’s essential to understand how to use self them with decorators. The self keyword refers to the instance of the class, and incorporating it with decorators can provide a way to enhance or alter the functionality of instance methods.

What is self With Decorator?

In Python, self is a reference to the instance of the class, and it is a common convention to name the first parameter of a method in a class as self. When using decorators with instance methods, you need to include self both the method definition and the decorator. This ensures that the instance is properly passed to the decorator, allowing you to access and modify instance attributes within the decorator.

Syntax

class MyClass:

def __init__(self):

# Constructor code here

@my_decorator

def my_method(self, other_parameters):

# Method code here

How To Use Self With Decorator?

Below, are the code example of How To Use self With Decorator.

Example 1: Logging Decorator

In this example, code defines a decorator called log_method_call that, when applied to a method, prints messages before and after its execution, including the method name and instance. The decorator is then used on the add method of the Calculator class, enhancing it with logging functionality. When an instance of Calculator is created and the add method is called, the decorator prints informative messages and returns the result of the original method.

Python3




def log_method_call(func):
    def wrapper(self, *args, **kwargs):
        print(f"Calling {func.__name__} with instance {self}...")
        result = func(self, *args, **kwargs)
        print(f"{func.__name__} finished. Result: {result}")
        return result
    return wrapper
 
class Calculator:
    def __init__(self):
        pass  # Constructor code here
 
    @log_method_call
    def add(self, a, b):
        return a + b
 
# Usage
calc = Calculator()
result = calc.add(3, 5)


Output

Calling add with instance <__main__.Calculator object at 0x7ff8cfef01d0>...
add finished. Result: 8

Example 2: Authorization Decorator

In this example, code defines a decorator authorize_access that is applied to the sensitive_operation method of the SecureResource class. The decorator checks whether the is_authorized attribute of the instance is True. If authorized, it allows the execution of the original method; otherwise, it raises a PermissionError. In below usage example, an instance of SecureResource is created with authorization enabled, and the sensitive_operation method is called.

Python3




def authorize_access(func):
    def wrapper(self, *args, **kwargs):
        if self.is_authorized:
            return func(self, *args, **kwargs)
        else:
            raise PermissionError("Unauthorized access")
 
    return wrapper
 
class SecureResource:
    def __init__(self, is_authorized=True):
        self.is_authorized = is_authorized
 
    @authorize_access
    def sensitive_operation(self):
        print("Access granted. Performing sensitive operation.")
        return "Operation completed."
 
# Usage
secure_resource = SecureResource(is_authorized=True)
result = secure_resource.sensitive_operation()


Output

Access granted. Performing sensitive operation.

Conclusion

In conclusion , Using self with decorators in Python allows you to create more dynamic and flexible class methods. It enables you to access and modify instance attributes within the decorator, opening up possibilities for implementing features like logging, authorization checks, or any other custom behavior. Understanding the syntax and incorporating self appropriately in both the method.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads