Python Function decorator | Novice tutorial
CSDN:python Detailed explanation of ornaments
in short ,python Decorator is a function used to expand the original function function , What's special about this function is that its return value is also a function , Use python The advantage of decorators is to add new functions without changing the original function code .
def hi(name="yasoob"):
return "hi " + name
print(hi())
# output: 'hi yasoob'
# We can even assign a function to a variable , such as
greet = hi
# We are not using parentheses here , Because we're not calling hi function
# It's putting it in greet In variables . Let's try to run this
print(greet())
# output: 'hi yasoob'
# If we delete the old hi function , See what happens !
del hi
print(hi())
#outputs: NameError
print(greet())
#outputs: 'hi yasoob'
Define a function in a function :
def hi(name="yasoob"):
print("now you are inside the hi() function")
def greet():
return "now you are in the greet() function"
def welcome():
return "now you are in the welcome() function"
print(greet())
print(welcome())
print("now you are back in the hi() function")
hi()
#output:now you are inside the hi() function
# now you are in the greet() function
# now you are in the welcome() function
# now you are back in the hi() function
# It shows that whenever you call hi(), greet() and welcome() Will be called at the same time .
# then greet() and welcome() Function in hi() Cannot be accessed outside the function , such as :
greet()
#outputs: NameError: name 'greet' is not defined
ef hi(name="yasoob"):
def greet():
return "now you are in the greet() function"
def welcome():
return "now you are in the welcome() function"
if name == "yasoob":
return greet
else:
return welcome
a = hi()
print(a)
#outputs: <function greet at 0x7f2143c01500>
# It clearly shows `a` Now point to hi() Function greet() function
# Now try this
print(a())
#outputs: now you are in the greet() function
What needs to be noted here is : stay if/else
In statement we return greet
and welcome
, instead of greet()
and welcome()
. Because when you put A pair of parentheses Put it in the back , This function will execute ; However, if you don't put the parentheses after it , Then it can Be passed around , And you can Assign to another variable without executing it .
for example : When we execute hi()()
when , It is equivalent to executing hi()
, here hi()
return greet
, Add another parenthesis , Equivalent to execution greet()
def hi():
return "hi yasoob!"
def doSomethingBeforeHi(func):
print("I am doing some boring work before executing hi()")
print(func())
doSomethingBeforeHi(hi)
#outputs:I am doing some boring work before executing hi()
# hi yasoob!
there doSomethingBeforeHi
Before each function passed in is executed, a sentence will be printed to indicate the program being executed
def a_new_decorator(a_func):
def wrapTheFunction():
print("I am doing some boring work before executing a_func()")
a_func()
print("I am doing some boring work after executing a_func()")
return wrapTheFunction
def a_function_requiring_decoration():
print("I am the function which needs some decoration to remove my foul smell")
a_function_requiring_decoration()
#outputs: "I am the function which needs some decoration to remove my foul smell"
a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
#now a_function_requiring_decoration is wrapped by wrapTheFunction()
a_function_requiring_decoration()
#outputs:I am doing some boring work before executing a_func()
# I am the function which needs some decoration to remove my foul smell
# I am doing some boring work after executing a_func()
a_new_decorator
The function of is to print a sentence before and after the execution of a specific function to indicate that the function is about to be executed and that the execution is completed , When we want to use these two directives every time we call a function , The most basic approach is to call ```a_new_decorator`` Pass the function to be used as an argument , That is to say
a_new_decorator(a_function_requiring_decoration)
def a_new_decorator(a_func):
def wrapTheFunction():
print("I am doing some boring work before executing a_func()")
a_func()
print("I am doing some boring work after executing a_func()")
return wrapTheFunction
@a_new_decorator
def a_function_requiring_decoration():
"""Hey you! Decorate me!"""
print("I am the function which needs some decoration to "
"remove my foul smell")
a_function_requiring_decoration()
#outputs: I am doing some boring work before executing a_func()
# I am the function which needs some decoration to remove my foul smell
# I am doing some boring work after executing a_func()
#the @a_new_decorator is just a short way of saying:
a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
In function a_function_requiring_decoration()
There is a sentence before the definition of @a_new_decorator
, This is the decorator , We will find that , In the direct call a_function_requiring_decoration()
when , It will print two sentences that we expect to indicate the function call , Be similar to :
In function a_function_requiring_decoration()
Add before the definition of @a_new_decorator
, In execution a_function_requiring_decoration()
when , The default is @a_new_decorator(a_function_requiring_decoration)
It should be noted that , At this point, if we execute :
print(a_function_requiring_decoration.__name__)
# Output: wrapTheFunction
Will find ,Ouput
The output should be "a_function_requiring_decoration", But it outputs wrapTheFunction
, This is my understanding :
Whether it's execution a_function_requiring_decoration()
, Or simply as an object a_function_requiring_decoration
Called / Pass on , This function adds... Before the definition @a_new_decorator
, It means that its essence is no longer a_function_requiring_decoration
It is a_new_decorator(a_function_requiring_decoration)
, therefore a_function_requiring_decoration.__name__=a_new_decorator(a_function_requiring_decoration).__name__=wrapTheFunction.__name__
a_function_requiring_decoration()=a_new_decorator(a_function_requiring_decoration)()=wrapTheFunction()
In this case , The decorator's function will rewrite the name of our function and the annotation document (docstring)
If you don't want a function to be replaced by a function in the decorator , have access to Python A simple function provided to us , That's it functools.wraps
One python Functions can also be decorated with multiple decorators , If there are multiple decorators , What is the execution order of these decorators ?
def decorator1(func):
return lambda:"<1>"+func()+"<1>"
def decorator2(func):
return lambda:"<2>"+func()+"<2>"
@decorator1
@decorator2
def func():
return "hello"
print(func())
#<1><2>helllo<2><1>
therefore , When a function is decorated with multiple decorators , The order of execution is First, execute the close to the function definition , Then execute the far from the function definition .
The previous examples use decorators that are essentially functions to decorate other functions , In fact, you can also use the class definition to define a decorator
class Decorator(object):
def __init__(self, f):
self.f = f
def __call__(self):
print("decorator start")
self.f()
print("decorator end")
@Decorator
def func():
print("func")
func()
#decorator start
#func
#decorator end
from functools import wraps
def a_new_decorator(a_func):
@wraps(a_func)
def wrapTheFunction():
print("I am doing some boring work before executing a_func()")
a_func()
print("I am doing some boring work after executing a_func()")
return wrapTheFunction
@a_new_decorator
def a_function_requiring_decoration():
"""Hey yo! Decorate me!"""
print("I am the function which needs some decoration to "
"remove my foul smell")
print(a_function_requiring_decoration.__name__)
# Output: a_function_requiring_decoration