博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
函数__装饰器
阅读量:4554 次
发布时间:2019-06-08

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

一.装饰器.

 装饰器: 在目标函数前和后插入一段新的代码,不改变原来的代码.装饰器是对原来基础功能的扩展和开放,又不变动原代码,所以比较安全.

装饰器语法

 

# 通用装饰器写法:# python里面的动态代理.# 存在的意义: 在不破坏原有函数和原有函数调用的基础上. 给函数添加新的功能def wrapper(fn): #  fn是目标函数.    def inner(*args, **kwargs): # 为了目标函数的传参        '''在执行目标函数之前.....'''        ret = fn(*args, **kwargs) # 调用目标函数, ret是目标函数的返回值        '''在执行目标函数之后....'''        return ret  # 把目标函数返回值返回. 保证函数正常的结束    return inner@wrapper  # target_func = wrapper(target_func) #此处的wrapper 一定记住:是不加括号的,不是调用!!!def target_func():    pass# target_func = wrapper(target_func) # 此时fn就是target_functarget_func() # 此时执行的是inner

 

 

 

下面是简易版装饰器 def play(username, password):    print("双击lol")    print("登录", username, password)    print("选择狂战士")    print("进草丛")    return "月之光芒"def xiaoxiaole(qq):    print("登录qq账号")    print("消消乐")def wrapper(fn): # fn = play    def inner(*args, **kwargs): # 无敌传参  接受到的是元组 ("alex", 123)        print("开挂")        ret = fn(*args, **kwargs) # 接受到的所有参数. 打散传递给正常的参数        return ret 接收函数的返回值    return innerplay = wrapper(play) # play = innerret = play('alex',"123")print(ret)输出结果:开挂双击lol登录 alex 123选择狂战士进草丛月之光芒

带参数的装饰器(装饰器的开关).

def wrapper_out(flag): # 装饰器本身的参数    def wrapper(fn): # 目标函数        def inner(*args, **kwargs): # 目标函数执行需要的参数            if flag == True:  #如果开关为False,就不进行函数的装饰                print("问问金老板. 行情怎么样啊") #执行函数之前                ret = fn(*args, **kwargs) # 在执行函数本身                print("金老板骗我. 恨你") #执行函数之后                return ret            else:                ret = fn(*args, **kwargs)  #执行函数本身                return ret        return inner    return wrapper# 语法糖 @装饰器@wrapper_out(True) # 先执行wrapper_out(True) 返回一个装饰器   再和@拼接  @装饰器def yue(): # 被 wrapper装饰    print("走啊. 约不?")yue()

 

解释1:不理解为何会变?:写完一个函数之后,不指定对象的调用它,你print这个函数,打印出来的内容,除了函数里的,一定还有它自己的返回值,说白了,此时的调用完之后,函数已经变成了它自己的返回值解释2:此时,这里变成了@wrapper,是个语法糖,就是python设计的语法上的简写,他和后面定义的函数,合在一起等值于  b=wrapper(b)(此时的函数名b就等于inner函数名,再调用就是调用的inner()函数) 解释3: 如果这里的参数True改为False,那么就无法执行该函数,会报错,这里的Alex(True)是让函数正常执行,执行完了,会变成该函数的返回值 → wrapper,而@wrapper下面定义的函数意味着,就是wrapper函数括号里参数, 而你再用这个参数名接收返回值,该函数名就变成了返回值,你之后再调用的实际是装饰器内部的函数,如果你想关闭装饰器,就把True,改为Flase,就可以了

装饰器的应用:

# 装饰器在登陆验证方面的应用.flag =False   #没登陆的状态为Falsedef login():   #此函数为登陆函数,只有登陆成功,才会显示成功登陆的状态(flag = True)    global flag    zhanghao =input("请输入账号:")    mima = input("请输入密码:")    if zhanghao=="alex" and mima=="123":        flag = True        return "登陆成功"    else:        print("对不起,输入有误.")        exit()def zhuangshi1(a):     def zhuangshi(fn):  #装饰器函数        def inner(*can1,**can2):                while 1:                    if flag == True:                        print("装饰器把你装饰了一番,你NB了")                        ret = fn(*can1,**can2)                        return ret,"从此人生达到巅峰!" #此处有多个返回值,会变成元组形式返回                    else:                        print("对不起,您还没登陆.")                        login()        return inner     return zhuangshi@zhuangshi1(True)def wangzhe(a,b):    print("玩家",a,"进入了游戏")    return "得到月之光芒剑"a = wangzhe("alex","123456")print(a)打印结果为:对不起,您还没登陆.请输入账号:alex请输入密码:123装饰器把你装饰了一番,你NB了玩家 alex 进入了游戏('得到月之光芒剑', '从此人生达到巅峰!')

 多个装饰器装饰同一个函数:

def wrapper1(fn):    def inner(*args, **kwargs):        print("装饰1111111")        ret = fn(*args, **kwargs)        print("装饰1111111")        return ret    return innerdef wrapper2(fn):    def inner(*args, **kwargs):        print("装饰2222222")        ret = fn(*args, **kwargs)        print("装饰2222222")        return ret    return inner#就近原则@wrapper1 #后被它装饰@wrapper2 #先被此装饰器装饰def func():    print("我是幸运的func")func()输出结果为:装饰1111111装饰2222222我是幸运的func装饰2222222装饰1111111

def wrapper_out(flag): # 装饰器本身的参数    def wrapper(fn): # 目标函数        def inner(*args, **kwargs): # 目标函数执行需要的参数            if flag == True:                print("问问金老板. 行情怎么样啊")                ret = fn(*args, **kwargs) # 在执行目标函数之前                print("金老板骗我. 恨你")                return ret            else:                ret = fn(*args, **kwargs)  # 在执行目标函数之前                return ret        return inner    return wrapper

# 语法糖 @装饰器@wrapper_out(True) # 先执行wrapper_out(True) 返回一个装饰器   再和@拼接  @装饰器def yue(): # 被 wrapper装饰    print("走啊. 约不?")
yue()

转载于:https://www.cnblogs.com/lgw1171435560/p/10118794.html

你可能感兴趣的文章
蓝桥杯java 基础练习 FJ的字符串
查看>>
jQuery文档处理
查看>>
[国嵌攻略][119][Linux中断处理程序设计]
查看>>
upstream实现内网网站在公网访问
查看>>
排序——归并排序
查看>>
JAVA实现对服务器的访问的两种方法
查看>>
搭建GitLab的Hexo博客记录
查看>>
NYOJ 496 [巡回赛-拓扑排序]
查看>>
redis五种数据类型的使用
查看>>
Form表单中的onClick,onSubmit和submit
查看>>
Python-SocketServer源码
查看>>
JavaScript-基本数据类型
查看>>
CentOS 7.3 实体机启动 U 盘制作
查看>>
mysql数据库
查看>>
dede调用文章里的图片
查看>>
windows 窗体基本控件
查看>>
unix date 命令获取某日期的前一天
查看>>
团队作业(二)
查看>>
[hdu 2604] Queuing 递推 矩阵快速幂
查看>>
c# js 删除table原行数据
查看>>