Decorators¶

Decorators are function that takes a function as an argument and outputs another function. They change the behaviour of the function without changing the function itself.

In [1]:
def smart_pow(func):

    def inner(*args, **kwargs):
        if isinstance(args[1], float) or args[1] < 0.0:
            return func(args[0]**args[1], 1)
        else:
            return func(*args, **kwargs)

    return inner

def smart_fact(func):

    def inner(*args, **kwargs):
        if args[0] < 0:
            raise ArithmeticError("Argument can't be less than 0")
        if isinstance(args[0], float):
            from math import gamma
            return gamma(args[0]+1.0)
        else:
            return func(*args, **kwargs)

    return inner

smart_pow and smart_fact are decorators for functions pow and fact respectively

In [2]:
@smart_pow
def pow(x, y):
    if y == 0:
        return 1
    return x * pow(x, y - 1)

@smart_fact
def fact(x):
    if x == 0:
        return 1
    return x * fact(x - 1)

Driver Code¶

In [3]:
if __name__ == "__main__":
    try:
        print(pow(2, 3))
        print(pow(2, 3.5))

        print(fact(5))
        print(fact(5.5))
        
        print(fact(-2.0))
    except Exception as exc:
        print('Exception:', str(exc))
8
11.313708498984761
120
287.8852778150444
Exception: Argument can't be less than 0