python之装饰器

高阶函数,返回值是一个函数(定义函数并不会执行函数的内容,调用时才会执行)

1.有小题如下

2

2.创建装饰器

# 创建装饰器,要求如下:
# 创建add_log装饰器,被装饰的函数打印日志信息;
# 日志格式为:字符串时间  函数名;运行时间;运行返回值结果
import time
import functools


def add_log(fun):                                     装饰器
    @functools.wraps(fun)                        调用模块
    def wrapper(*args,**kwargs):              接受可以是变量  也可以是关键字函数

        ctime=time.ctime()
        funname=fun.__name__

        starttime = time.time()
        res=fun(*args,**kwargs)                  装饰函数,在此处返回原函数并执行
        endtime=time.time()
        print("[%s] 函数名:%s 运行时间为:%.6f 运行返回结果:%s" % (ctime,funname,endtime - starttime,res))
        return res
    return wrapper

@add_log
def logmessags():

    return 'hello world'

logmessags()

执行结果如下:

3.函数有返回值的解决办法

import random                                                                                           导入随机数模块
import time                                                                                                导入时间模块
import string                                                                                              导入字符串模块
import functools                                                                                                    
li=[random.choice(string.ascii_letters)  for i  in range(1,100) ]                随机挑选100个字母


def timeit(fun): # con_add
    @functools.wraps(fun)           ##保留被装饰函数的函数名和帮助文档信息
    def wrapper(*args,**kwargs):###接收可变参数和关键字参数
        # 函数执行前
        starttime = time.time()
        # 执行函数
        res=fun(*args,**kwargs)##args解包
        # 函数执行后
        endtime = time.time()
        print("运行时间为:%.6f" % (endtime - starttime))
        return res
    return  wrapper

@timeit
def con_add():
    s = ''
    for i in li:
        s += (i+",")
    print(s)
con_add()

@timeit
def join_add():
    print(",".join(li))
join_add()

@timeit
def con_list(n):
    print([i*2 for i in range(n)])
con_list(20)

@timeit
def con_map(n):
    return list((map(lambda x:x*2 , range(n))))
print(con_map(20))

实验如下

 4.在装饰器里函数中嵌套函数

 # 解决问题:1.在函数执行之前和之后添加功能,调用函数的方式改变了
 #2.不改变原有函数的调用方法:函数里面嵌套函数,并且返回嵌套的函数
  def desc(fun):       # fun=login    需要传递一个函数,即要装饰的函数
       def add_info():   ###装饰器函数里面嵌套函数
           print('hello')
           fun()                    ###login()

           print('welcome')
       return add_info        ##3返回值是嵌套函数
 
  def login():
      print('login...')
  login=desc(login)          ###返回值是一个函数
  login()

 

 

5.用户登录装饰器

 需求:用户登录验证的装饰器
 1)如果用户登陆成功,则执行被装饰的函数
 2)如果用户登陆不成功,则执行登陆函数

   import functools
   login_users=['root','admin']

   def is_login(fun):                                         # fun: writeBlog
      @functools.wraps(fun)
      def wrapper(*args, **kwargs):                  name="admin"    kwargs={"name":"admin"}    判断写博客的这个用户是否登陆成功

          news( )                                               
          if kwargs.get("name") in login_users:
              res = fun(*args, **kwargs)
              return res
          else:
              res=login()
          return res
      return wrapper
 
  @is_login
    必须登陆成功
  def writeBlog(name):
      return 'write'
  def login():
      return 'please login in'
    是否登陆成功均可进入
  def news():
      print('news/。。。')


  print(writeBlog(name='admin'))

 

 

6.无参数的装饰器

# 编写装饰器required_ints,条件如下:
# 1)确保函数接到的每一个参数均为整数
# 2)如果参数不是整形数,打印TypeError:参数必须为整形

import functools
def required_ints(fun):
    @functools.wraps(fun)
    def wrapper(*args, **kwargs):
        for i in args:                                                    i 在变量中遍历
            if not  isinstance(i,int):                                如果i 不是整形
                return 'TypeError: 参数必须为整形'
                break
        else:
            res=fun(*args,**kwargs)
            return res
    return wrapper
@required_ints
def add(a,b):
    return a+b

print(add(1,6) )
print(add(1,1.0))
@required_ints
def Max(a,b,c,d):
    return max(a,b,c,d)                           #返回a,b,c,d中的最大值
print(Max(1,2,3,4))

            

 

 

7.有参数的装饰器(升级版)

import functools
def required_types(*kinds):                                                   在原有装饰器前再定义一个函数,此时要求如果不是整形或浮点型则
    def required(fun):                                                               报错,否则执行之。
        @functools.wraps(fun)
        def wrapper(*args,**kwargs):
            for i in args:
              if not isinstance(i,kinds)
                    return('Error')
            else:
                res=fun(*args,**kwargs)
                  return res
        return wrapper
      return required
@required_types(int,float)
def add(a,b):
    return a+b
 print(add(1,2.0))
 print(add(2+2j))

 结果为:3.0

 结果为:Error

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值