Python中函数装饰器及练习

1)装饰器的理解:

 

   1、作用:在不改变原函数的基础上,给函数增加功能

    2、返回值:把一个函数当作参数,返回一个替代版的函数

   3、本质:返回函数的函数

   4、应用场景:计时器、记录日志、用户登陆认证、函数参数认证

2)无参函数装饰器

    实例: 被装饰的函数没有参数

   

   执行结果为:

   

3)有参函数装饰器

    实例:当年龄小于0时,均输出0

   

4)装饰器练习

  1、定时器(获取每个函数的执行时间)  

 import time
 import string
 import random
 import functools
 # 随机生成24个大小写英文字母
 li = [random.choice(string.ascii_letters) for i in range(24)]
 def getTime(fun):
@functools.wraps(fun)
def wrapper(*args, **kwargs):
start_time = time.time()
rest = fun(*args,**kwargs)
end_time = time.time()
print "函数运行时间为:%.6f" %(end_time-start_time)
return rest
return wrapper 

 @getTime
 def
con_add():      # 使用+来连接
    sum = " "
    for
i in li:
        sum += (i+',')
    print
sum
    return
0
 @getTime
 def join_add():    # 使用内置函数join来连接
print ','.join(li)
return 1

 
print con_add()    # 进行调用
 print
join_add()
 
显示结果如下:由此可见,使用内置函数运行时间小于普通函数。
 

 
注意:一、当被装饰函数有返回值的时候:我们需要在装饰函数里面,对被装饰函数调用进行接收;然后返回接收值就可以显示被装饰函数的返回值了!
       二、如何保留被装饰函数的函数名和帮助文档信息:导入functools包,并进行调用即可
 2、记录日志:打印的日志格式为:【字符串时间】 函数名: xx 运行时间:xx 运行返回值:xx
 import time
 import functools
 def add_log(fun):
  @functools.wraps(fun)
  def wrapper(*args,**kwargs):
  start_time = time.time()
  ret = fun(*args,**kwargs)
  end_time = time.time()
  print '[%s] 函数名:%s 运行时间:%.6s 运行的返回值的结果:%d' \
  %(time.ctime(),fun.__name__,end_time-start_time,ret)
 return wrapper
 @add_log
 def Log(x,y):
  time.sleep(1)
  return x+y
 Log(1,2.2)
 
显示运行结果:

 
 
3、验证用户的登陆认证(登陆成功执行被装饰函数;失败继续执行登陆)
 
import functools
 login_user = ['admin', 'root']
 def
is_login(fun):
    @functools.wraps(fun)
    def wrapper(*args, **kwargs): # 可以使用第一个元组值来判断
       if kwargs.get('name') in login_user:
          res = fun(*args, **kwargs)
          return res
       else:
          res = login()
          return res
    return
wrapper
 @is_login
 def writeBlog(name):
    return "写博客..."
 def login():
return "登陆..."
print writeBlog(name = 'admin')      # 此用户可以登陆;执行结果为'写博客...'
 
注释:一个函数,可以有多个装饰器来修饰
 
4、函数参数认证:
 
1)、当装饰器为@required_typeint,float):确保函数接受到的每一个参数为intfloat
  2)、当装饰器参数为list,确保每一个参数类型均为list
  3)、当参数为(str,int):确保函数接受到的每一个参数为str
int
 
4)、类型
若以上参数均不满足,打印TypeError:参数必须是xxx
 import functools
  def required_type(*type):
 def required_all(fun):
  @functools.wraps(fun)
  def wrapper(*args, **kwargs):
  for i in args:
  if isinstance(i, type):
  pass
  else:
  print 'typeError:函数所有的参数并非', type
  break
 else:
  res = fun(*args, **kwargs)
  return res
  return wrapper
 return required_all
  @required_type(list)
  def add(a, b):
  return a + b
  print add([1,2],2)
 

 

posted @ 2018-09-06 11:21  UTHN_B  阅读(588)  评论(0)    收藏  举报