Decorators, iterators, generators, built-in functions

1. Decorator

1. Decorator: add functions before and after the original function without changing the calling method of the original function

Example 1 (Decorator with no arguments): Calculate the execution time of the func1 function (calculate the running time of a function)

import time 
def timer (f):
def inner ():
starttime = time.time ()
ret = f ()
endtime = time.time ()
print ('函数 耗时 :% s'% (endtime-starttime))
return ret
return inner

def func1 ():
print ('begin ....')
time.sleep (0.1)
print ('end ....')
return 666

func1 = timer (func1)
func1 ()


执行 结果 :

begin....
end....
function time: 0.1000056266784668

 

The above is not written in the form of @timer, it can be rewritten as:

import time
def timer(f):
def inner():
starttime=time.time()
ret=f()
endtime=time.time()
print('函数耗时:%s'% (endtime-starttime))
return ret
return inner
@timer
def func1():
print('begin....')
time.sleep(0.1)
print('end....')
return 666

result=func1()
print(result)
执行结果:

begin....
end....
function time: 0.1000056266784668
666

 

Example 2 (Decorator with parameters)

import time
def timer(f):
def inner(*args,**kwargs):
starttime=time.time()
ret=f(*args,**kwargs)
endtime=time.time()
print('函数耗时:%s'% (endtime-starttime))
return ret
return inner
@timer
def func1(a,b):
print('begin....',a)
time.sleep(0.1)
print('end....',b)
return True

result=func1(100,101)
print(result)

执行结果:

begin.... 100
end.... 101
Function time: 0.1000056266784668
True

 

Summary: The structure of the decorator is as follows 

In short, this is an outer function, define an inner inner function, return inner function

# def timmer(f): 
# def inner(*args,**kwargs):
# Functions that can be added before calling a function
# ret = f(*args,**kwargs)
# Functions that can be added after calling a function
# return ret
# return inner

 

2. Advanced requirements

In the first case, 500 functions, you can design your decorator to confirm whether it works (consider passing parameters to the decorator)

Example 1:

import time
def outetr(flag): 
def timmer(f):
def inner(*args,**kwargs):
if flag==True:
start_time = time.time()
ret = f(*args,**kwargs)
end_time = time .time()
print(end_time - start_time)
else:
ret = f(*args, **kwargs)
return ret
return inner
return timmer

@outetr(True) # func = timmer(func) so outetr(True), this only The function outetr is executed, the rest is not executed, and timmer is returned. It is equivalent to outetr(True)=timmer, so that @timmer will execute the following
def func(a,b):
print('begin func',a)
time.sleep(0.1)
print('end func',b)
return True

ret = func(1,2) #--> inner()


Results of the:

begin func 1
end func 2
0.10100579261779785

 

If the parameter passed to the decorator is false

import time 
def outetr(flag):
def timmer(f):
def inner(*args,**kwargs):
if flag==True: ##The inner function uses the variable of the outer function
start_time = time.time()
ret = f (*args,**kwargs)
end_time = time.time()
print(end_time - start_time)
else:
ret = f(*args, **kwargs)
return ret
return inner
return timmer

@outetr(False) # func = timmer( func)
def func(a,b):
print('begin func',a)
time.sleep(0.1)
print('end func',b)
return True

ret = func(1,2) #--> inner( )

execution result:

begin func 1
end func 2

 

The above can be transformed into:

import time 
FLAG = True ##All variables, if there are 500 functions, look at the definition below
def outer(flag):
def timmer(f):
def inner(*args,**kwargs):
if flag == True:
start_time = time.time()
ret = f(*args,**kwargs)
end_time = time.time()
print(end_time - start_time)
else:
ret = f(*args, **kwargs)
return ret
return inner
return timmer

@outer(FLAG) # func = timmer(func)
def func(a,b):
print('begin func',a)
time.sleep(0.1)
print('end func',b)
return True

func( 1,2)

Results of the:

begin func 1
end func 2
0.1000056266784668 #If FLAG=False, there is no result of this line, and the rest are

The second case: two functions decorate the same function at the same time

def wrapper1(func): #f passed in 
def inner1():
print('wrapper1 ,before func')
func() #f
print('wrapper1 ,after func')
return inner1

def wrapper2(func): #innner1 passed Come in
def inner2():
print('wrapper2 ,before func')
func() #inner1
print('wrapper2 ,after func')
return inner2

@wrapper2 #f=warpper2(f) At this time f is inner1 f=wrapper2 (inner1)=inner2
@wrapper1 #f=wrapper1(f) =inner1
def f():
print('in f')

f() #This sentence is equal to

the execution result of inner2():

wrapper2 ,before func
wrapper1 ,before func
in f
wrapper1 ,after func
wrapper2 ,after func

 The order of execution is as follows:

 

 Example (last week's day03 homework can be done in a similar way)

# Decorator login log 
import time
login_info = {'alex':False}
def login(func): # manager
def inner(name):
if login_info[name] != True:
user = input('user:')
pwd = input('pwd :')
if user == 'alex' and pwd == 'alex3714':
login_info[name] = True
if login_info[name] == True:
ret = func(name) # inner
return in timmer ret
return inner

def timmer(f):
def inner(*args,**kwargs):
start_time = time.time()
ret = f(*args,**kwargs) # call the decorated method
end_time = time.time( )#
print(end_time - start_time)
return ret
return inner

@login
@timmer
def index(name):
print('Welcome %s to the homepage of Blog Park~'%name)

@login
@timmer # manager = login(manager)
def manager( name):
print('Welcome %s to the blog garden management page~'%name)

index('alex')
index('alex')
manager('alex')
manager('alex')

# Calculate index and manager Execution time

execution result:

user : alex
pwd : alex3714
welcome alex to the blog garden homepage~
0.0
welcome alex to the blog garden homepage~
0.0
welcome alex to the blog garden management page~
0.0
welcome alex to the blog garden management page~
0.0

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325258379&siteId=291194637