详解python中的装饰器


Posted in Python onJuly 10, 2018

在了解装饰器之前,我们需要知道什么闭包是什么鬼!

闭包:在一个函数内定义了一个函数f,并且这个函数f引用外部变量,在把这个函数f当做返回值返回。

上述说了闭包的三个条件:

1 函数内定义了一个函数f

2 f函数引用了外部变量

3 f被当做返回值返回

def t1():#定义t1函数
 x=2
 def f():#t1函数内部定义了f函数
  print(x)#f函数引用了不属于自己内部的变量x
 return f #f被当做返回值返回

而装饰器有是什么鬼呢?其实闭包的一种运用。

装饰器:在不改变函数(当然还有其他的)的代码和调用方式的前提下,为函数增加新的功能!

那么需求来了:例如我定义了一个下载方法,我在想不改变下载方法的代码和调用方式,为其加一个需要登录后才能下载的功能

def get(file):#下载方法
 print('下载成功',file)

那么如何实现呢?这里就要用到上面提到的闭包。

我们再来看看闭包,即是在一个函数内定义了一个函数f,并且这个函数f引用外部变量,在把这个函数f当做返回值返回

那么上面的需求我们可以先试着做第一步,即是不改变下载方法的代码,为其加一个需要登录后才能下载的功能

def get(file):#下载方法
 print('下载成功',file)
def auth(get,*args,**kwargs):
 print('登录方法')
 get(*args,**kwargs)
auth(get,'a.txt')
#结果:
#登录方法
#下载成功 a.txt

但是这样的话调用方式改变了,那么我们可以利用闭包:

def get(file):#下载方法
 print('下载成功',file)
def func(get):
 def auth():
  print('登录方法')
  get()
 return auth
get=func(get)
get('dasd')

这样的话,参数有传不进去,并且报错参数没有接收到:

我们分析一下上面代码 func(get)其实应该是auth这函数名,那么get=func(get),就是把auth赋值给get变量,即是次数 get=auth,

那么 我们调用get('dasd') 即是auth('dasd'),即是我们需要修改auth函数

def get(file):#下载方法
 print('下载成功',file)
def func(get):
 def auth(file):
  print('登录方法')
  get(file)
 return auth
get=func(get)
get('dasd')

这样的话get('dasd')的时候就是调用auth('dasd'),那么会执行登录方法,并且执行get('dasd'),这里是真正的下载方法

优化一下就是这样的:

def auth(f):
 def wrapper(*args,**kwargs):
  print('其它功能或方法')
  f(*args,**kwargs)
 return wrapper

这样的要装饰get函数的时候,只需get=auth(get),这里第一个get是变量,第二个get是函数名,这样就实现get不改变其的代码和调用方式,为其增加功能。

在python中 get=auth(get),可以省略为:

def auth(f):
 def wrapper(*args,**kwargs):
  print('登录方法')
  f(*args,**kwargs)
 return wrapper
@auth # 相当于get=auth(get)
def get(file):#下载方法
 print('下载成功',file)

当然上面是装饰器的无参装饰器,还有有参装饰器:

#有参装饰器
def authx(a):
 def auth(f):
  def wrapper(*args, **kwargs):
   if a=='a':
    print('登录方法')
   else:
    print('adad')
   f(*args, **kwargs)
  return wrapper
 return auth

@authx('adas') # 相当于get=auth(get) 当然 a的值也传入了
def get(file):#下载方法
 print('下载成功',file)

总结

以上所述是小编给大家介绍的python中的装饰器,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python中input和raw_input的一点区别
Oct 21 Python
Python实现的数据结构与算法之基本搜索详解
Apr 22 Python
Python 正则表达式入门(初级篇)
Dec 07 Python
python实现二维码扫码自动登录淘宝
Dec 27 Python
[原创]使用豆瓣提供的国内pypi源
Jul 02 Python
django框架之cookie/session的使用示例(小结)
Oct 15 Python
Python面向对象之类的内置attr属性示例
Dec 14 Python
python opencv捕获摄像头并显示内容的实现
Jul 11 Python
Python如何输出百分比
Jul 31 Python
Python实现手势识别
Oct 21 Python
pytorch--之halfTensor的使用详解
May 24 Python
python单元测试之pytest的使用
Jun 07 Python
pandas值替换方法
Jul 10 #Python
Pandas 数据处理,数据清洗详解
Jul 10 #Python
python+pandas+时间、日期以及时间序列处理方法
Jul 10 #Python
使用Python的Dataframe取两列时间值相差一年的所有行方法
Jul 10 #Python
Python Dataframe 指定多列去重、求差集的方法
Jul 10 #Python
Python实现对文件进行单词划分并去重排序操作示例
Jul 10 #Python
python3中函数参数的四种简单用法
Jul 09 #Python
You might like
vBulletin Forum 2.3.xx SQL Injection
2006/10/09 PHP
php获取某个目录大小的代码
2008/09/10 PHP
PHP实现今天是星期几的几种写法
2013/09/26 PHP
PHP中实现生成静态文件的方法缓解服务器压力
2014/01/07 PHP
使用PHP和HTML5 FormData实现无刷新文件上传教程
2014/09/06 PHP
PHP验证信用卡卡号是否正确函数
2015/05/27 PHP
PHP微信公众号开发之微信红包实现方法分析
2017/07/14 PHP
php微信开发之图片回复功能
2018/06/14 PHP
最新优化收藏到网摘代码(digg,diigo)
2007/02/07 Javascript
JavaScript库 开发规则
2009/01/31 Javascript
in.js 一个轻量级的JavaScript颗粒化模块加载和依赖关系管理解决方案
2011/07/26 Javascript
JS获取浏览器版本及名称实现函数
2013/04/02 Javascript
兼容各大浏览器的JavaScript阻止事件冒泡代码
2015/07/09 Javascript
JS实现新浪微博效果带遮罩层的弹出框代码
2015/10/12 Javascript
JQuery实现简单的服务器轮询效果实例
2016/03/31 Javascript
AngularJS 单元测试(二)详解
2016/09/21 Javascript
详细AngularJs4的图片剪裁组件的实例
2017/07/12 Javascript
详解node Async/Await 更好的异步编程解决方案
2018/05/10 Javascript
Express之托管静态文件的方法
2018/06/01 Javascript
iView框架问题整理小结
2018/10/16 Javascript
node将geojson转shp返回给前端的实现方法
2019/05/29 Javascript
python socket网络编程步骤详解(socket套接字使用)
2013/12/06 Python
python实现bitmap数据结构详解
2014/02/17 Python
浅析Git版本控制器使用
2017/12/10 Python
Python网络编程基于多线程实现多用户全双工聊天功能示例
2018/04/10 Python
jupyter 中文乱码设置编码格式 避免控制台输出的解决
2020/04/20 Python
python3.7调试的实例方法
2020/07/21 Python
国际知名军事风格休闲装品牌:Alpha Industries(阿尔法工业)
2017/05/24 全球购物
英国发展最快的在线超市之一:Click Marketplace
2021/02/15 全球购物
俄语专业毕业生推荐信
2013/10/28 职场文书
毕业生就业推荐信范文
2013/12/01 职场文书
女大学生自我鉴定
2013/12/09 职场文书
优秀老员工获奖感言
2014/02/15 职场文书
2014年实验室工作总结
2014/12/03 职场文书
校园运动会广播稿
2015/08/19 职场文书
Spring Boot项目传参校验的最佳实践指南
2022/04/05 Java/Android