DEV Community

Cover image for What is @try 🤯 before this function in Python?
Rajesh Joshi
Rajesh Joshi

Posted on

What is @try 🤯 before this function in Python?

History ⏳

I was looking into the code base of a library few years back ⌚, and I saw something strange 🤯. It goes like -

@try
def fetch(url: str):
    resp = request.get(url)
    return resp.json()
Enter fullscreen mode Exit fullscreen mode

So the definition of fetch function is clear enough, but what the hack is this @try 🤯 just before the function definition?


That was a Decorator 🤔

Decorators are very powerful and useful tool in Python as it allows programmers to modify the behaviour of a function. Decorators allow us to wrap another function in order to extend the behaviour of the wrapped function.


Scary Definition 😨, Let's understand with examples

Example 1: Functions as an object 🤔

def upper_text(text):
    return text.upper()

print(upper_text('Hello'))

func = upper_text

print(func('Hello'))
Enter fullscreen mode Exit fullscreen mode
HELLO
HELLO
Enter fullscreen mode Exit fullscreen mode

Example 2: Function as an argument 🤔

def upper_text(text):
    return text.upper()

def lower_text(text):
    return text.lower()

def func(func):
    # storing the function in a variable
    msg = func("Hello")

    print(msg)

func(upper_text)
func(lower_text)
Enter fullscreen mode Exit fullscreen mode
HELLO
hello
Enter fullscreen mode Exit fullscreen mode

Example 3: Returning function 🤔

def create_adder(x):
    def adder(y):
        return x + y

    return adder

add_15 = create_adder(15)

print(add_15(10))
Enter fullscreen mode Exit fullscreen mode
25
Enter fullscreen mode Exit fullscreen mode

Example 4: Decorator 🚀

# importing libraries
import time
import math

# decorator to calculate duration
# taken by any function.
def calculate_time(func):

    # added arguments inside the inner1,
    # if function takes any arguments,
    # can be added like this.
    def inner1(*args, **kwargs):

        # storing time before function execution
        begin = time.time()

        func(*args, **kwargs)

        # storing time after function execution
        end = time.time()
        print("Total time taken in : ", func.__name__, end - begin)

    return inner1

# this can be added to any function present,
# in this case to calculate a factorial
@calculate_time
def factorial(num):

    # sleep 2 seconds because it takes very less time
    # so that you can see the actual difference
    time.sleep(2)
    print(math.factorial(num))

# calling the function.
factorial(10)
Enter fullscreen mode Exit fullscreen mode
3628800
Total time taken in :  factorial 2.0061802864074707
Enter fullscreen mode Exit fullscreen mode

Back to History 😃

So, what was that?

@try
def fetch(url: str):
    resp = request.get(url)
    return resp.json()
Enter fullscreen mode Exit fullscreen mode

The definition of try was like this -

def try(func):
    def exe(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            return {
                "message": "Error while processing the request",
                "details": str(e)
            }
    return exe
Enter fullscreen mode Exit fullscreen mode

Hit Like ❤️ and share your thoughts in the comments 💬


Thank you

cheers

Top comments (2)

Collapse
 
leotrs profile image
Leo Torres

Where was this @try decorator defined? It's not doing much and in fact except Exception as e is a huge code smell.

Collapse
 
rajeshj3 profile image
Rajesh Joshi

You are right @leotrs, this particular case is not an excellent implementation of decorator. But, this was just an easy to understand example, that hopefully will help a lot of programmers to understand how it works.

Happy Coding