博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python_11 装饰器,闭包
阅读量:4970 次
发布时间:2019-06-12

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

装饰器:本质就是函数,功能是为其他函数添加附加功能

原则:

1.不修改被修饰函数的源代码

2.不修改被修饰函数的调用方式

装饰器的知识储备

装饰器=高阶函数+函数嵌套+闭包

 

#装饰器:def timmer(func):    def wrapper(*args,**kwargs):        time1=time.time()        res=func(*args,**kwargs)        time2=time.time()        print('函数的运行时间是%d'%(time2-time1))        return res    return wrapper@timmerdef cal(l):    res=0    for i in l:        res+=i        time.sleep(0.1)    return resa=cal(range(10))print(a)>>>函数的运行时间是145

 

高阶函数定义:

1.函数接收的是一个函数名

2.函数的返回值是一个函数名

3.满足上述任意一个条件都可以称之为高阶函数

 

import timedef foo():    time.sleep(0.5)    print("sadfa")def test(func):    print(func)    t1=time.time()    func()    t2=time.time()    print("函数的运行时间是%ds"%(t2-t1))test(foo)#修改了函数的调用方式

 

#不修改源代码#不修改foo调用方式#多运行了一次,不合格def foo():    time.sleep(1)    print("from the foo")def dec(func):    t1=time.time()    func()    t2=time.time()    print("%s的运行时间是%d"%(func,(t2-t1)))    return funcfoo=dec(foo)foo()

函数的闭包:闭包是由函数及其相关的引用环境组合而成的实体,如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。

def father(name):    print('from father %s'%name)    def son():        print('my father is %s'%name)        def grandson():            print('my grandpa is %s'%name)        grandson()    son()    print(locals())father('alex')>>>from father alexmy father is alexmy grandpa is alex{
'son':
.son at 0x00000169A59B7268>, 'name': 'alex'}

装饰器框架:

#装饰器框架def timmer(func):    def wapper():        print(func)        func()    return wapper
def timmer_test(func):    def add_time():        t1=time.time()        func()        t2=time.time()        print('该函数的运行时间是%d'%(t2-t1))    return add_timedef test():    time.sleep(2)    print('test函数运行完毕')test=timmer_test(test)test() >>>test函数运行完毕该函数的运行时间是2

 

@语法糖:

def timmer(func):    def add_time():        t1=time.time()        func()        t2=time.time()        print('该函数的运行时间是%d'%(t2-t1))    return add_time@timmer#@timmer 就相当于test=timmer(test)def test():    time.sleep(2)    print('test函数运行完毕')test()>>>test函数运行完毕该函数的运行时间是2

函数闭包加上返回值:

def timmer(func):    def add_time():        t1=time.time()        res=func()        t2=time.time()        print('该函数的运行时间是%d'%(t2-t1))        return res    return add_time@timmer#@timmer 就相当于test=timmer(test)def test():    time.sleep(2)    print('test函数运行完毕')    return '这是test的返回值'res=test()#这里就是在运行add_timeprint(res)>>>test函数运行完毕该函数的运行时间是2这是test的返回值

再加上参数:

def timmer(func):    def add_time(*args,**kwargs):        t1=time.time()        res=func(*args,**kwargs)        t2=time.time()        print('该函数的运行时间是%d'%(t2-t1))        return res    return add_time@timmer#@timmer 就相当于test=timmer(test)def test(name,age):    time.sleep(2)    print('test函数运行完毕,名字是%s,年龄是%d'%(name,age))    return '这是test的返回值'@timmerdef test1(name,age,gender):    time.sleep(3)    print('test1函数运行完毕,名字是%s,年龄是%d,性别是%s'%(name,age,gender))    return '这是test1的返回值'res=test('alex',19)#这里的test是运行的add_timeprint(res)res1=test1('sb',20,'male')print(res1)>>>test函数运行完毕,名字是alex,年龄是19该函数的运行时间是2这是test的返回值test1函数运行完毕,名字是sb,年龄是20,性别是male该函数的运行时间是3这是test1的返回值

 

解压序列:

a,b,c='hel'print(a,b,c)e,f,g=(4,5,6)print(e,f,g)#取出第一个值和最后两个值l=['alex',7,8,9,7,8,5,2,1,5,6,4,8,6,4,6,'is','sb']#*_代表中间所有的值,_可以换成任意值x,*_,y,z=lprint(x,y,z)>>>h e l4 5 6alex is sb

调换两变量的值:

a=20b=100a,b=b,aprint(a,b)>>>100 20

 

装饰器加上验证功能:

 

user_dic={
'name':None,'login':False}def yanzheng(func): global zt def wapper(*args,**kwargs): if user_dic['name'] and user_dic['login']: res=func(*args,**kwargs) return name=input('请输入用户名:').strip() psw=input('请输入密码:').strip() if name=='alex' and psw=='123': res=func(*args,**kwargs) user_dic['name']=name user_dic['login']=True return res else: print('用户名或密码错误') return wapper@yanzhengdef index(): print('欢迎来到京东主页')@yanzhengdef home(name): print('欢迎回家%s'%name)@yanzhengdef car(name): print('%s的购物车里有%s'%(name,'奶茶'))index()home('alex')car('alex')>>>请输入用户名:alex请输入密码:123欢迎来到京东主页欢迎回家alexalex的购物车里有奶茶

 

user_list=[    {
'user_name':'alex','psw':'123'}, {
'user_name':'blex','psw':'456'}, {
'user_name':'clex','psw':'789'}, {
'user_name':'dlex','psw':'0'}]current_zt={
'name':None,'login':False}def yanzheng(func): def wapper(*args,**kwargs): global user_name if current_zt['name'] and current_zt['login']: res=func(*args,**kwargs) return res user_name=input('请输入用户名:').strip() psw=input('请输入密码:').strip() for user_dic in user_list: if user_name==user_dic['user_name'] and psw==user_dic['psw']: res=func(*args,**kwargs) current_zt['name']=user_name current_zt['login']=True return res else: print('用户名或密码错误') return wapper@yanzhengdef index(): print('欢迎来到京东主页')@yanzhengdef home(): print('欢迎回家%s'%user_name)@yanzhengdef car(): print('%s的购物车里有%s'%(user_name,'奶茶'))index()home()car()>>>请输入用户名:blex请输入密码:456欢迎来到京东主页欢迎回家blexblex的购物车里有奶茶

 

将原装饰器加上参数:直接在最外层加一个函数带上参数,使用装饰器时也需带上参数

user_list=[    {
'user_name':'alex','psw':'123'}, {
'user_name':'blex','psw':'456'}, {
'user_name':'clex','psw':'789'}, {
'user_name':'dlex','psw':'0'}]current_zt={
'name':None,'login':False}def renzhen(type='ldb'): def yanzheng(func): def wapper(*args,**kwargs): global user_name print('认证类型是%s'%type) if type=='ldb': if current_zt['name'] and current_zt['login']: res=func(*args,**kwargs) return res user_name=input('请输入用户名:').strip() psw=input('请输入密码:').strip() for user_dic in user_list: if user_name==user_dic['user_name'] and psw==user_dic['psw']: res=func(*args,**kwargs) current_zt['name']=user_name current_zt['login']=True return res else: print('用户名或密码错误') elif type=='abb': print('不知道这个类型') res = func(*args, **kwargs) return res else: print('类型错误') res = func(*args, **kwargs) return res return wapper return yanzheng@renzhen(type='ldb')def index(): print('欢迎来到京东主页')@renzhen(type='abb')def home(): print('欢迎回家%s'%user_name)@renzhen(type='sss')def car(): print('%s的购物车里有%s'%(user_name,'奶茶'))index()home()car()

 

转载于:https://www.cnblogs.com/Manuel/p/10637930.html

你可能感兴趣的文章
C++模式设计-多线程下的单例模式
查看>>
[转载]ASP.NET对路径"xxxxx"的访问被拒绝的解决方法小结
查看>>
20180601_Chrome中安装JsonView插件
查看>>
8款非常棒的响应式 jQuery 幻灯片插件推荐
查看>>
【MATLAB 从零到进阶】day2 矩阵 数组
查看>>
Eclipse常用的十个方便的快捷键
查看>>
[HNOI 2003] 消防局的设立
查看>>
多少人知道需求规格说明书是什么
查看>>
java 高级用法笔记
查看>>
@Autowired与@Resource的使用方法和差别
查看>>
算法练习题---罗马数字转int
查看>>
第十一周助教总结
查看>>
Python的安装与小程序的编写
查看>>
Linux常见命令
查看>>
C# 拆箱与装箱 要严格控制,数量多起来严重影响效率
查看>>
分享一篇关于C#对文件操作的日志,方法很全
查看>>
Python调用(运行)外部程序
查看>>
C#实体类对象修改日志记录
查看>>
Java设计模式の装饰者模式
查看>>
Facebook内部高效工作PPT指南
查看>>