Search code examples
pythonpython-decorators

python decorator wraps twice?


Encounter a strange problem with python decorator by accident, basically when I directly call decorator function, the original function being wrapped got wrapped twice.

Some simple code to show the problem:

def my_deco(f):
    def wrapper(*args):
        print('some code before')
        f(*args)
        print('some code after')
    return wrapper

@my_deco
def original_func(text):
    print   (f'original func print {text}')

then command 1):

original_func('hello')

will print (which is correct by the way):

some code before
original func print hello
some code after

but command 2):

my_deco(original_func)('hello')

will print below:

some code before
some code before
original func print hello
some code after
some code after

Was expecting same results between two commands, but the latter command seems to wrap the original function twice. when I run both commands without parentheses, they both correctly point to the wrapper function, but the results are different once executed with parentheses.

I kind of convinced myself with below logic, but still feel uncomfortable so I am looking for comments or correction on my thinking:

command 1): call original_func -> my_deco -> wrapper -> wrapping + original_func execution

command 2): call my_deco -> wrapper -> wrapping + original_func execution (it is wrapped version)

So it looks like the original_func in command 1) remains as "original" no wrapping; and the original_func in command 2) is "wrapped" version.

Thanks in advance.


Solution

  • When you defined original_func you use a decorator so python wraped it. In command 2) you wraped it again youself so the result is the function being wraped twice.
    If you ran the following, the output should be right:

    def original_func(text):
        print   (f'original func print {text}')
    
    my_deco(original_func)('hello')