详解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开发的nosql数据库CodernityDB介绍和使用实例
Oct 23 Python
Python random模块常用方法
Nov 03 Python
深入Python解释器理解Python中的字节码
Apr 01 Python
在Python的Django框架中编写错误提示页面
Jul 22 Python
python去除扩展名的实例讲解
Apr 23 Python
Python模拟登录的多种方法(四种)
Jun 01 Python
python文件操作之批量修改文件后缀名的方法
Aug 10 Python
python覆盖写入,追加写入的实例
Jun 26 Python
对YOLOv3模型调用时候的python接口详解
Aug 26 Python
python词云库wordcloud的使用方法与实例详解
Feb 17 Python
基于python实现计算且附带进度条代码实例
Mar 31 Python
Java byte数组操纵方式代码实例解析
Jul 22 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
PHP生成短网址的3种方法代码实例
2014/07/08 PHP
PHP数组操作――获取数组最后一个值的方法
2015/04/14 PHP
php基于websocket搭建简易聊天室实践
2016/10/24 PHP
php基于ob_start(ob_gzhandler)实现网页压缩功能的方法
2017/02/18 PHP
ThinkPHP框架结合Ajax实现用户名校验功能示例
2019/07/03 PHP
PHP实现二维数组(或多维数组)转换成一维数组的常见方法总结
2019/12/04 PHP
Aliyun Linux 编译安装 php7.3 tengine2.3.2 mysql8.0 redis5的过程详解
2020/10/20 PHP
js 单引号 传递方法
2009/06/22 Javascript
一个简单的js鼠标划过切换效果
2010/06/30 Javascript
关于extjs treepanel复选框选中父节点与子节点的问题
2013/04/02 Javascript
怎么清空javascript数组
2013/05/11 Javascript
NodeJs基本语法和类型
2015/02/13 NodeJs
如何使用jquery实现文字上下滚动效果
2016/10/12 Javascript
Bootstrap复选框和单选按钮美化插件(推荐)
2016/11/23 Javascript
js遍历json的key和value的实例
2017/01/22 Javascript
React-Native中禁用Navigator手势返回的示例代码
2017/09/09 Javascript
jquery鼠标悬停导航下划线滑出效果
2017/09/29 jQuery
Vue中使用vue-i18插件实现多语言切换功能
2018/04/25 Javascript
JavaScript实现像雪花一样的Hexaflake分形
2020/07/07 Javascript
python如何在终端里面显示一张图片
2016/08/17 Python
Python 字符串大小写转换的简单实例
2017/01/21 Python
使用XML库的方式,实现RPC通信的方法(推荐)
2017/06/14 Python
tensorflow实现逻辑回归模型
2018/09/08 Python
Python基础之高级变量类型实例详解
2020/01/03 Python
pymysql之cur.fetchall() 和cur.fetchone()用法详解
2020/05/15 Python
python能否java成为主流语言吗
2020/06/22 Python
Pycharm配置lua编译环境过程图解
2020/11/28 Python
英国在线房屋中介网站:Yopa
2018/01/09 全球购物
长曲棍球装备:Lacrosse Monkey
2020/12/02 全球购物
应聘医药代表职位求职信
2013/10/21 职场文书
初一英语教学反思
2014/01/11 职场文书
早读迟到检讨书
2014/01/24 职场文书
2015年个人实习工作总结
2014/12/12 职场文书
2016年五一国际劳动节活动总结
2016/04/06 职场文书
分析JVM源码之Thread.interrupt系统级别线程打断
2021/06/29 Java/Android
如何使用SQL Server语句创建表
2022/04/12 SQL Server