Unlike java, python uses nested functions to implement decorators.
This could be tricky when we first try to understand.
A few features of python are applied:
- python functions are objects.
- nested function defines are allowed.
- functions can return function objects.
Decorator functions without arguments are different with functions with argument.
Notice the differences in following code:
def simpledecorator(func):
print("This function is decorated with a decorator with no argument.")
def actual(*args, **kwargs):
return func(*args, **kwargs)
return actual
"""
Followings are the same as:
def simpleprint(message):
print("Hello %s" % message)
simpledecorator(simpleprint)("simple decorator!")
"""
@simpledecorator
def simpleprint(message):
print("Hello %s" % message)
simpleprint("simple decorator!")
print("\n========\n")
def decorator_with_args(arg1, arg2):
def innerdecorator(func):
print("This function is decorated with with a decorator with argument %s, %s" % (arg1, arg2))
def actual(*args, **kwargs):
return func(*args, **kwargs)
return actual
return innerdecorator
"""
Followings are the same as:
def print_again(message):
print("Hello %s" % message)
decorator_with_args(arg1, arg2)(print_again)("decorator with arguments!")
"""
@decorator_with_args("a1", "a2")
def print_again(message):
print("Hello %s" % message)
print_again("decorator with arguments!")
output:
This function is decorated with a decorator with no argument.
Hello simple decorator!
========
This function is decorated with with a decorator with argument a1, a2
Hello decorator with arguments!
Product | Price |
---|---|
Coffee | $25 |
Add milk | $25 |
Add cinnamon | $10 |
How much is a cup of coffee, add milk, add cinnamon cost?
def add_milk(func):
def actual(*args, **kwargs):
return func(*args, **kwargs) + 25
return actual
def add_cinnamon(func):
def actual(*args, **kwargs):
return func(*args, **kwargs) + 10
return actual
@add_milk
@add_cinnamon
def buy_mixed_coffee():
return 50
price = buy_mixed_coffee()
print("mixed price: %s" % price)
# add milk again
price = add_milk(buy_mixed_coffee)()
print("double milk price: %s" % price)
# the same as buy_mixed_coffee
def buy_coffee():
return 50
price = add_milk(add_cinnamon(buy_coffee))()
print("mixed price: %s" % price)
output:
mixed price: 85
double milk price: 110
mixed price: 85