Reputation: 37
I started learning decorators in python. I have below query ?
def add(a):
print 'This is an addition function'
return a
@add
def dollar():
print 'Am i getting the concept ?'
dollar()
This call giving me the output as
This is an addition function
Am i getting the concept ?
But if I am calling the function like this i am getting the below error
def add(a):
a
print 'This is an addition function'
@add
def dollar():
print 'Am i getting the concept ?'
dollar()
This is an addition function
Traceback (most recent call last):
File "D:\Python Programs\Sample\src\TestRuns.py", line 10, in <module>
dollar()
TypeError: 'NoneType' object is not callable
MY Query is when we call the function with argument a in return its working. But when we call argument a individually its not working ?
Upvotes: 0
Views: 311
Reputation: 73460
A decorator must return a callable/function which it doesn't in your second version.
@add
def dollar():
print 'Am i getting the concept ?'
is short for:
def dollar():
print 'Am i getting the concept ?'
dollar = add(dollar)
Hence:
def add(a):
a # this line doesn't do anything!
print 'This is an addition function'
# this line is executed upon decoration
@add # prints 'This is an addition function'
def dollar():
print 'Am i getting the concept ?'
# BUT: dollar is now None, since add didn't return anything
# SO:
dollar()
# fails
The way you write that first version of your decorator suggest that you are not really getting the concept. Usually one decorates that function in order to manipulate the behaviour of that function. Your first decorator does not change dollar
at all! The additional print
only happens once at decoration time, NOT when the decorated function is called:
dollar()
dollar()
dollar()
# Output
This is an addition function # decoration
Am i getting the concept ? # dollar execution
Am i getting the concept ? # dollar execution
Am i getting the concept ? # dollar execution
If you want the decorator to add that extra line of output to every call of the decorated function you should do sth like this:
def add(a):
def dec_a():
print 'This is an addition function'
a()
return dec_a # return the augmented function
# Output
This is an addition function # decoration
Am i getting the concept ? # dollar execution
This is an addition function # decoration
Am i getting the concept ? # dollar execution
This is an addition function # decoration
Am i getting the concept ? # dollar execution
Upvotes: 3
Reputation: 1216
Decorator is a method that operates on other methods before execution of that method. So it must return and function object at the end of the decorator function. Removing the return statement is returning None, and preventing the execution of dollar method
Upvotes: 0