I have always had trouble really understanding some of Python’s advanced concepts. I just thought I finally understood decorators and ran into another wall.
As I understand, the core truth to decorators is that the following two things are exactly the same:
@function_generator
def original_function:
...
and
original_function = function_generator(original_function)
which is to say that what is being done is that function_generator
is being called and passed the original_function
, then function_generator
hands back a different function which then is given the original function’s name, so that when the code calls the original_function
, what really gets executed is the code the function generator returns.
But then I tried this:
def decorator(passed_func, times):
"""the decorator"""
def replacement():
"""the replacement"""
for i in range(times):
passed_func()
return replacement
#@decorator
def print_name():
"""prints my name"""
print("My name is Benn")
iterate = int(input("How many times?"))
print_name = decorator(print_name, iterate)
print_name()
This code works fine and does exactly what I expect. But when I uncomment the @decorator
and comment out print_name = decorator(print_name, iterate)
, it crashes.
The reason I ran this code test is because I was seeing an advanced example of decorators where they said we have to wrap the decorator in a whole other function to pass in arguments (like iterate
). However, it seems to me that if that is true it makes the statement that @func2
is merely syntactic sugar for typing func1=func2(func1)
into a lie.
So which of the following is true:
typing
func1=func2(func1)
is NOT exactly the same as@func2
over thedef
forfunc1
, because if it was, then iffunc1=func2(func1,arg)
works then@func2
as a decorator would work; orthey are the same even though from the above example it seems exactly the opposite – if so, why does it seem the opposite?
That's what I am hung up on right now. Why do so many people say that @decorator
is nothing but another way to write func1=decorator(func1)
when it does not work that way when you add an argument in to the mix?