前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python学习(五)---- 不可不知的装饰器!

Python学习(五)---- 不可不知的装饰器!

作者头像
智能算法
发布2018-08-17 16:19:45
3850
发布2018-08-17 16:19:45
举报
文章被收录于专栏:智能算法智能算法智能算法

原文地址:

https://blog.csdn.net/fgf00/article/details/52061971

编辑:智能算法,欢迎关注!

今天一起学习装饰器的相关知识。


1. 装饰器基础

1.1 介绍

  • 器:代表函数的意思。装饰器本质就是是函数
  • 功能:装饰其他函数,就是为其他函数添加附加功能

被装饰函数感受不到装饰器的存在

  • 原则
    1. 不能修改被装饰的函数的源代码(比如线上环境)
    2. 不能修改被装饰的函数的调用方式
  • 实现装饰器知识储备:
    1. 函数即是“变量”
    2. 高阶函数
    3. 嵌套函数

1.2 通过高阶函数+嵌套函数==>实现装饰器

先分析以下两段代码能不能运行?

第二段代码报错:

1.3 变量知识回顾

  • 定义变量:

如:定义变量:x=1,会在内存中找块内存空间把“1”存进去,把“1”的内存地址给x , 前面提到:函数即变量

  • python内存回收机制

是解释器做的。解释器到底怎么去回收这个变量?

python解释器当中有种概念叫做引用计数。什么叫引用计数呢?

比如:定义x=1,之后又定义了y=1或y=x,实际上又把内存空间“1”的内存地址赋值给y

这里x代表一次引用,y代表一次引用。加起来两次引用。

python什么时候会把“1”这个内存空间清空呢?会回收内存呢?

当x这个变量没有了,y这个变量也没有了,便会把“1”这个内存空间清掉

  • 匿名函数

匿名函数没有函数名,没有引用,所以会被垃圾回收机制立马回收掉。

所以匿名函数要赋值给变量,把函数体赋值给变量名

现在可以再理解下最开始两段代码能不能运行的原因。


2. 高阶函数

什么叫高阶函数呢:

a. 把一个函数名当做形实传给另外一个函数

b.返回值中包含函数名

2.1 把一个函数名当做形实传给另外一个函数

运行结果(打印内存地址)

如下代码,能不能运行:

函数即变量,像“x=1,y=x”,同样f是一个是一个函数,可不可以像一个变量一样来回赋值呢?

到这里,貌似实现了装饰函数的功能。

看上面装饰器的原则:

这里:没有修改func1的源代码,但是调用方式改变了。现在是test1(func1),之前是func1() ,现在能做到哪一点呢?

把一个函数名当做实参传给另外一个函数(不修改被装饰的函数源代码的情况下为其添加功能)

2.2 返回值中包含函数名

运行结果:

把函数内存地址都打印出来了,看到这么多内存地址,有什么想法?

加上小括号就能运行。

上面代码“test2(func2())” 和 “test2(func2)”有什么区别?加上小括号是函数返回结果,不加是函数内存地址。所以加上小括号就不符合高阶函数定义了。

既然以后有了函数的内存地址,是不是可以赋值给其他变量?

好像还没什么用,怎么让他有用呢?

把test2(func2)赋值给func2

这就是高阶函数的第二个好处:返回值中包含函数名(不修改函数的调用方式)


3. 嵌套函数

嵌套函数:在一个函数体内,用def去声明一个函数

看一下下面的代码是不是嵌套:

注意函数嵌套和函数调用区别,局部作用域和全局作用域的访问顺序:


4. 装饰器

4.1 装饰器

前面铺垫了那么多,现在开讲正题:装饰器

先用高阶函数实现给函数不修改源代码的情况下添加功能

按照上面说的,如何实现不改变调用方式?直接“test1 = deco(test1)”和“test2 = deco(test2)”吗?

别忘记了,第二种方式,高阶函数要加上return,如下

虽然没有修改源代码和调用方式,但是函数加上return,函数就结束了,然并卵。怎么实现呢?

前面一直在用高阶函数,还没有用嵌套函数,加上嵌套函数能不能实现呢?看一下

到此,完成实现了装饰器的功能。但是还是有点麻烦,如何能不要“test1 = timer(test1)”,

python解释器提供了语法糖“@”符合,给哪个函数新增功能,就加在哪个函数头部

4.2 有参装饰器

前面实现了装饰器的功能,但是如果函数有参数,能不能也能运行呢

报错:丢失参数

@timer 相当于 test2=timer(test2) =deco

test2() 相当于运行deco(),所以没指定参数,报错。

如何传参数呢?为了适应各种不同参数的函数

4.3 终极装饰器

注意,上面的例子中还没有涉及返回值,看下面的例子可以体会一下

假设:公司网站需要验证登录,有不同的验证方式:本地认证、LDAP认证等


声明:本文系网络转载,版权归原作者所有。如涉及版权,请联系删除!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-08-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 智能算法 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档