different between "return func" and "return func()"

62 Views Asked by At

Firstly, I'm so sorry if this is a dupplicated question.

let's say I have a simple python code named decorator.py with decorator here:

def decorator(func):
    def wrapper():
        print("Before function.")
        val = func()
        print("After function.")
        return val
    return wrapper() # <- please pay attention to this line`

@decorator
def hello():
    print("hello!")

@decorator
def good_bye():
    print("good_bye!")

@decorator
def thank_you():
    print("thank_you!")

@decorator
def thanks_a_lot():
    print("thanks_a_lot!")

the result after running the code

Before function.
hello!
After function.
Before function.
good_bye!
After function.
Before function.
thank_you!
After function.
Before function.
thanks_a_lot!
After function.
[Finished in 46ms]

this mean, return wrapper() calls all my functions? what is the difference between wrapper() and wrapper in this case. I appreciate for your explaination.

I'm tring to run on debug mode to find out, but still got nothing, I hope I'll get a detail explaination

3

There are 3 best solutions below

1
terpinmd On

In this case calling wrapper() would immediately execute the function. if you just return wrapper, then you are returning the function itself so that it can be called later by another part of the code

EDIT

I am going to come up with a contrived example to illustrate what I mean in the above explanation:

An immediately executed function might be like this:

def hello_world():
    print("Hello, World!")

# Call the function to execute it
hello_world()

In the above case as you expect "Hello, World!" is printed immediately.

You can also reference functions in variables like:

def hello_world():
    print("Hello, World!")

# Assign the function to a variable
hello_function = hello_world

# Call the variable as a function
hello_function()

In the above case we created a variable hello_function that references the same hello_world function and then LATER executes it with hello_function()

You could then do slick things like pass that function around to other functions creating higher order functions.

0
Jean-Baptiste Yunès On

wrapper() is an expression that calls the function, execute its instructions and catch the returned result. Thus if you write a = wrapper() then a will be set to the returned value.

wrapper is an expression that represents the function itself, no more no less. When you have an expression, say e that corresponds to a function, you can call it using (). So, if you write a = wrapper, a is set to a value that represent a callable function. You can then write a() to call it.

If you change return wrapper() to return wrapper, you can observe that nothing will be printed as the wrapper is never called, so anything it wraps is not executed.

0
Sagar Chandra Dey On

While, a function is passed as an argument, we generally pass the function name. For example, let's say, we have a number of functions, where we will define "we will do this, then this and this and so on."

def hello():
    return "Hello"

user_name = input("Your name : ")

def name(name):
    return name

def condition():
    return "How are you?"

def greet(func1, func2, func3):
    return func1() + ' ' + func2(user_name) + '! ' + func3()

print(greet(hello, name, condition))`

when we passing the arguments(hello, name, condition), the function is not called yet. the function is triggered while we add the parenthesis(func1(), func2(), func3()). This concept is called higher order functions

Let me know if it helps you a bit.