Python - Decorators

25.
Discuss the use of decorators in method overloading and polymorphism.

In Python, method overloading and polymorphism can be achieved using decorators to provide a flexible and dynamic behavior based on the types or number of arguments passed to a function.

# Example illustrating decorators in method overloading and polymorphism

# Decorator for method overloading based on argument types
def overload(func):
    registry = {}

    def register(*types):
        def decorator(f):
            registry[types] = f
            return f
        return decorator

    def dispatcher(*args, **kwargs):
        types = tuple(type(arg) for arg in args)
        return registry[types](*args, **kwargs)

    func.register = register
    func.dispatcher = dispatcher
    return func

# Applying the decorator for method overloading
@overload
def calculate(*args, **kwargs):
    """Calculate method with method overloading."""
    pass

@calculate.register(int, int)
def calculate_int_int(x, y):
    return x + y

@calculate.register(str, str)
def calculate_str_str(s1, s2):
    return s1 + s2

# Calling the overloaded method
result1 = calculate(1, 2)
result2 = calculate('Hello', ' World')

In this example:

  • Decorator for Method Overloading: The @overload decorator is used to create a function (calculate) that supports method overloading. It has an associated register function and dispatcher function.

  • Registering Overloaded Methods: The calculate.register decorator is used to register overloaded methods for different argument types. In this example, methods are registered for (int, int) and (str, str) types.

  • Dispatcher: The dispatcher function is responsible for dispatching the call to the appropriate overloaded method based on the types of arguments passed.

Output:

# Output of the overloaded methods
result1 = calculate(1, 2)        # 3 (int + int)
result2 = calculate('Hello', ' World')  # Hello World (str + str)

The use of decorators in this example allows for method overloading based on the types of arguments, enabling polymorphism in the calculate function.