# What are decorators in Python?

Decorator is a function that takes another function as an argument and extends the behavior of the later function without explicitly modifying it. In other words, decorator wraps another function in order to extend the behavior of wrapped function.

In decorators, function are taken as the argument into another function and then called inside the wrapper function. Let's consider following example to understand the concept of decorators:

## Decorator Example

``````
# check_divisor is decorator function
def check_divisor(func):
def inner(a,b):
if b==0:
return "Divison by zero is not possible."
return func(a,b)
return inner

# Here we are using decorator function
# to check whether there is division by zero or not
@check_divisor
def divide(a,b):
return a/b

print(divide(4,5))
print(divide(40,0))
print(divide(400,5))
print(divide(23.4,0))
``````
##### Output
```0.8
Divison by zero is not possible.
80.0
Divison by zero is not possible.
```

## Explanation

In the python program above, `@check_divisor` is actual use of decorator function which extends the behavior of function `divide()`.

To understand how decorator function extends behavior of another function, lets consider how to write above code without using `@check_divisor`:

``````
def check_divisor(func):
def inner(a,b):
if b==0:
return "Divison by zero is not possible."
return func(a,b)
return inner

def divide(a,b):
return a/b

div = check_divisor(divide)

print(div(4,5))
print(div(40,0))
print(div(400,5))
print(div(23.4,0))
``````
##### Output
```0.8
Divison by zero is not possible.
80.0
Divison by zero is not possible.
```

### Stepwise Analysis

1. Here, `div = check_divisor(divide)` calls decorator function `check_divisor` which takes function `divide` as an argument which means `func` will get `divide`.
2. But, remember function `check_divisor` returns `inner` function back to variable `div`.
3. Now when we call `div` like `div(a,b)` then it actually calls `inner(a,b)` where it returns `"Divison by zero is not possible"` if ` b = 0` otherwise it returns `func(a,b)` so what is `func` here? It is `divide` function, right? Look step 1 of step wise explanation. So ` return func(a,b)` actually executes `return a/b` from function `divide(a,b)`.

### Back to @check_divisor

Here, writing `@check_divisor` before function definition of `divide` is similar to:

```divide = check_divisor(divide)
```

## Real Life Scenario for Decorator

The real life example of decorator can be used in Django to disable the unauthorized users from accessing the Django app. This can be done as `login_required()` decorator:

A default decorator has been made in `django.contrib.auth.decorators` for login required so,

``````
`login_required()` does the following:
1. If the user isn’t logged in, redirect to `settings.LOGIN_URL`, passing the current absolute path in the query string.