博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python之路day12--装饰器的进阶
阅读量:6632 次
发布时间:2019-06-25

本文共 5350 字,大约阅读时间需要 17 分钟。

装饰器 # 开发原则:开发封闭原则 # 装饰器的作用:在不改变原函数的调用函数下,在函数的前后添加功能。 # 装饰器的本质:闭包函数
import timedef timmer(f):  #func     #timmer就是一个装饰器函数    def inner():        start = time.time()        f() #用外部函数的变量f 是一个闭包  f()就是被装饰的函数        end = time.time()        print(end-start)    return inner #返回内部函数的名字(注意)@timmer   #语法糖 @装饰器函数名,下面必须是被装饰的函数def func(): #被装饰的函数    time.sleep(0.01)    print('大魔王法克儿')# func=timmer(func) #有了语法糖这一句就不用写了func()  #相当于是inner()

 

args:接受*就是聚合,调用加*就是打散

*args:接受*就是聚合,调用加*就是打散
# *args:接受*就是聚合,调用加*就是打散 def func(*args): #站在形参的角度上,给变量加上*,就是组合所有传来的值     print(args)  #(1, 2, 3, 4, 5)     print(*args) #1 2 3 4 5 func(1,2,3,4,5) #(1, 2, 3, 4, 5)

执行顺序  

装饰器想当与一个中介,

 

 

 wraps

def wahaha():    '''    一个函数    :return:    '''    print('娃哈哈')print(wahaha.__name__) #wahaha
def wrapper(func):  #func=holidy    def inner(*args,**kwargs):        print('在被装饰函数之前执行')        ret = func(*args,**kwargs)  #这个就是被装饰的函数        print('在被装饰函数之后执行')        return ret    return inner  #inner = holidy@wrapper #holidy=wrapper(holidy)  #调用wrapper,将holidy传进去,结果就是inner=holidydef holidy(day): print('放假%s天'% day) return '返回的是这里' ret = holidy(3) #inner() print(ret)
from functools import wrapsdef wrapper(func):  #func=holidy    @wraps(func) #    def inner(*args,**kwargs):        print('在被装饰函数之前执行')        ret = func(*args,**kwargs)  #这个就是被装饰的函数        print('在被装饰函数之后执行')        return ret    return inner  #inner = holidy @wrapper #holidy=wrapper(holidy) #调用wrapper,将holidy传进去,结果就是inner=holidy def holidy(day): '''holidy._doc_出现的内容''' print('放假%s天'% day) return '返回的是这里' print(holidy.__name__) print(holidy.__doc__) ret = holidy(3) #inner() # print(ret)

 

作业

# 1、编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件), # 要求登录成功一次,后续的函数都无需再输入用户名和密码。
FALG = False #定义一个全局变量def login(f):    def inner(*args,**kwargs):        global FALG        if FALG == True:            ret= f(*args,**kwargs)            return ret else: '''登录程序''' username = input('请输入你的账号:') password = input('请输入你的密码:') li=[] with open('The user data',mode='r+',encoding='utf-8') as f1: for line in f1: li.append(line) if username.strip() == li[0].strip() and password.strip() == li[1].strip(): FALG =True #全局变量=True ret = f(*args, **kwargs) return ret else: print('用户名或密码错误,请重试') return inner @login def shoplist_add(): print('增加一件物品') return 1 def shoplist_del(): print('减少一件物品') return 2 ret=shoplist_add() ret=shoplist_del() print(ret)
2、编写装饰器,为多个函数加上记录调用的功能,要求每次调用都将被调用的函数名称写入文件内
from functools import wrapsdef log_record(f):    # @wraps(f)    def inner(*args,**kwargs):        print('--start---')        ret=f(*args,**kwargs)        print('--record---') with open('log_record',mode='a+',encoding='utf-8') as f1: f1.write(f.__name__) return ret return inner @log_record def fun1(): return 1 ret =fun1() print(ret) @log_record def fun2(): return 2 ret =fun2() print(ret)
进阶 1、编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
import urllibfrom urllib.request import urlopendef get(url):    code = urlopen(url).read()    print(code)ret=get('https://www.baidu.com/') print(ret)
2、为题目1编写装饰器,实现缓存网页中内容的功能具体:实现下载的页面存放于文件中,如果文件中有值,就从文件中取,否则取下载存到文件中
import urllibfrom urllib.request import urlopenimport osdef cache(f):    def inner(*args,**kwargs):        if os.path.getsize('web_cache'): #如果有这个文件            with open('web_cache', mode='rb') as f1: return f1.read() else: ret=f(*args,**kwargs) with open('web_cache', mode='wb') as f1: f1.write(b'@@@@@@'+ret) return ret return inner @cache def get(url): code = urlopen(url).read() return code ret=get('https://www.baidu.com/') #第一次是从网站读出来的 print(ret) ret=get('https://www.baidu.com/')#二次是从自己文件中读出 print(ret) ret=get('https://www.baidu.com/')#三次是从自己文件中读出 print(ret)

装饰器的进阶(带参数的装饰器,多个装饰器装饰一个函数)

带参数的装饰器

#500个函数import timeFALGE=True  #用flag判断def timmer_out(flag): #flag 只是形参,参数是谁无所谓  #最外边的一层只是为了把FALGE传进,其他的并没有改变    def timmer(func):        def inner(*args,**kwargs):            if flag:  #如果flag 为true 则执行装饰器里计算时间的功能                start = time.time()                ret=func(*args,**kwargs) end =time.time() print(end - start) return ret else: ret = func(*args, **kwargs) return ret return inner return timmer # @timmer_out(FALGE) #先执行 timmer_out(FALGE)-->返回timmer给timmer_out,此时其实就为@timmer def wahaha(): time.sleep(0.1) print('wahhhhhhhhh') @timmer_out(FALGE) def xiaoyi(): time.sleep(0.2) print('xiaoyiyiyiyi') #FLAGE=false #在这里可以控制FLAGE wahaha() xiaoyi()

 

多个装饰器装饰一个函数 (俄罗斯套娃,一层一层)
def wrapper1(func):    def inner():        print('wrapper1,before func')        func()        print('wrapper1,after func')    return innerdef wrapper2(func): def inner(): print('wrapper2,before func') func() print('wrapper2,after func') return inner @wrapper2 @wrapper1 #靠近函数的这个装饰器先执行 def f(): print('in f') f() #结果 ''' wrapper2 wrapper1 in f wrapper1 wrapper2 '''

 

执行顺序:

 

ps:

def wrapper1(func):    def inner():        print('wrapper1,before func')        ret=func()        print('wrapper1,after func')        return ret return inner def wrapper2(func): def inner(): print('wrapper2,before func') ret = func() print('wrapper2,after func') return ret return inner @wrapper2 @wrapper1 #靠近函数的这个装饰器先执行 def f(): print('in f') return '哈哈哈' print(f()) #结果(但是结果是从上至下,可以理解为套娃) ''' wrapper2,before func wrapper1,before func in f wrapper1,after func wrapper2,after func 哈哈哈 ''' # ps: def f2(): print('in f') return '哈哈哈' print(f2()) ''' in f 哈哈哈 '''
用途: 记录用户的登录情况 计算这个函数的执行时间

 

 

转载于:https://www.cnblogs.com/hanfe1/p/10496894.html

你可能感兴趣的文章
Android DDMS 连接真机(己ROOT),用file explore看不到data/data文件夹的解决办法
查看>>
小项目中建立列表页时间需要注意的
查看>>
SQL Server 索引列的顺序——真的没关系吗
查看>>
Eclipse中Svn插件配置
查看>>
POI 设置EXCEL单元格格式(日期数字文本等)
查看>>
cocos2d-x lua 学习笔记(1) -- 环境搭建
查看>>
java.lang 类String
查看>>
去掉iPhone、iPad的默认按钮样式
查看>>
U盘去保护方法
查看>>
kmalloc/kfree,vmalloc/vfree函数用法和区别
查看>>
【转】 Android开发之EditText属性详解
查看>>
tomcat https 未测试成功的版本
查看>>
各大门户网站全局CSS样式定义
查看>>
Overfitting & Regularization
查看>>
Bootstrap看厌了?试试Metro UI CSS吧
查看>>
通过Java发送邮件和接收邮件的工具类
查看>>
理解SQL Server中的权限体系(上)----主体
查看>>
Android Map新用法:MapFragment应用
查看>>
强人工智能基本问题:全局控制与自组织
查看>>
音乐网站之技术总结
查看>>