This is Qing'an , In this chapter, let's talk about decorators in simple terms . We talked about decorators in the previous chapter . I don't know how much you understand . It doesn't matter if you read too much , Let's practice this chapter .
def outer(fun):
print("1....")
def inner():
print("2.....")
fun()
return inner
@outer
def count():
print("3....")
if __name__ == '__main__':
print("4....")
count()
def outer(fun):
print("1....")
def inner():
print("2.....")
fun()
return inner
def count():
print("3....")
count = outer(count)
print("4....")
count()
The two examples above , The execution result is :1423. Why? ???
Grammatical sugar : What is grammar sugar ?
We are count There is such a @outer The function name of , So what he actually means is count = outer(count). Then no @outer It's just like the example 2 equally . Replace the original with the same variable name , But the memory address has changed . In this way, a calling process is realized . It means a bit of cheating .
1、 After reading the above , Do you have a little understanding of why 1423 了 . First, it will enter the decorator, so it will execute print(“1…”) ----------------------------------------
2、 Complete step 1 , Then you need to print it analytically print(“4…”) 了 . Why? ? because outer The function is finished .----------------------------------------
3、 So why outer The function is finished , No output print(‘2…’)? Because we've changed our minds ,return 了 inner, Here's count() Namely inner(), So execute count() function , It's actually execution inner() So it will output print(‘2…’) ----------------------------------------
4、 So this print(‘3…’) Why did you output it last , Because we outer(count),count Parameters have been passed , In the decorator , stay inner At the end of, we call fun(). So the final output print(‘3…’)
Have you understood it now . If you don't understand , Then interrupt debug See how it works , Combine it and understand it again .
import time
def count_time(fun):
def inner():
st_time = time.time()
fun()
ed_time = time.time()
print(f" Function takes time {
ed_time-st_time}")
return stop
@count_time
def test01():
for i in range(5):
time.sleep(0.1)
print(" Being implemented Primitive function ")
if __name__ == '__main__':
test01()
As long as the previous content is understood , The example of function execution time here is easy to understand . Here is an additional time modular . Used to get the current time . therefore , The function executes to get the current time , Function ends to get the current time , Subtract the start time from the end time , Is the time spent in function execution .
In order to highlight the time spent in function execution , Here I also call time Medium sleep Method , Again test01 Waiting in . Wait after each cycle 0.1S.
import logging
def logger(fun):
def inner(*args,**kwargs):
logging.basicConfig(format='[ Time :%(asctime)s The level of logging :%(levelname)s file name :%(filename)s The first %(lineno)d That's ok :>>> Log information :%(message)s]',
level=logging.DEBUG)
logging.debug(f" Parameter is :{
args}")
logging.debug(f" The return value is :{
fun(*args,**kwargs)}")
reslut = fun(*args)
return reslut
return inner
@logger
def test1(num):
return num
@logger
def test02(num,number):
return num+number
if __name__ == '__main__':
test1(1)
test02(1,2)
Here is also a practical example , In the process of writing automated code , We need to add log information to our programs . Although it can be presented in the form of classes , Complete by calling . But I want to be tall , How to write it simply ?
Here I'll take you a brief look !
Here is also very simple , Import logging modular , Call the basicConfig Method , Specify the format of writing, that is format. Specify the log information detail . Then call to output the information of what level of detail , And specify some parameters , That is to say logging.debug() It's about . In this way, you can get a simple log information . Look at the screenshot :