当前位置: 首页 > python > python学习教程 > python从零开始(被称之为神器的装饰器)

python从零开始(被称之为神器的装饰器)

更新时间:2019-10-10 15:10:21 来源:环球网校 浏览137收藏41
摘要 假设今天我中了500万,我打算在北京买一个厕所,厕所的功能就是大小便,我觉得需要加点什么,给厕所改造一下,但是要保证厕所的功能,添加一面镜子,再来个热水器,装个喷头。一个三星级厕所打造成功。这个过程就和我们的装饰器差不多了,这就是被称之为神器的装饰器。

一、装饰器

保证原来功能的同时添加新的功能。

1、装饰即修饰,意指为其他函数添加新功能

2、装饰器定义:本质就是函数,功能是为其他函数添加新功能

装饰器原则?

1.不修改被装饰函数的源代码(开放封闭原则)

2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式

看看这个过程

我们先定义一个函数

def fun(): print('我是厕所,我的功能是让人们大小便') fun()#我是厕所,我的功能是让人们大小便

添加一个镜子

def fun(F): print('我是厕所,我的功能是让人们大小便') fun1() def fun1(): print('我是镜子,我的功能是供人梳妆打扮用') fun(fun1)# 我是厕所,我的功能是让人们大小便# 我是镜子,我的功能是供人梳妆打扮用

调用函数,我们却改变了原来函数的代码结构,

自己添加功能的话,还需要改动代码

要是代码量超级大,十万行代码,别说去改,打开看一下,把代码看懂都费劲,然而有了装饰器这个神器,就不用这么麻烦了。

上面的问题,我们这样做。

def fun(): print('我是厕所,我的功能是让人们大小便') def fun1(func): def func_add(): print('我是镜子,我的功能是供人梳妆打扮用') func() return func_add() #这里返回函数包含(),直接运行fun1(fun)# 我是厕所,我的功能是让人们大小便# 我是镜子,我的功能是供人梳妆打扮用

也是调用函数但是不是修改原函数,而是将原函数传给了新的函数,这算不上是装饰器,

这就相当于,我买的厕所,后面成了化妆间,厕所成了附带功能,

python给我们提供了,另一个神奇的东西,语法糖,@

我们修改上面的实现

def fun1(func): def func_add(): print('我是镜子,我的功能是供人梳妆打扮用') func() return func_add@fun1def fun(): print('我是厕所,我的功能是让人们大小便')fun()# 我是镜子,我的功能是供人梳妆打扮用# 我是厕所,我的功能是让人们大小便

看,我们直接调用的原函数fun(),得到的功能却是添加新功能后的。

这就是装饰器,

分析过程:

1、我们写了一个新的函数fun1,函数内部嵌套了一个函数(func_add),嵌套的函数 调用了一个传入的函数func,然后最外层函数返回了 嵌套的函数func_add,这里我们返回的函数不能加(),

2、将 新功能函数fun1 采用 @fun1 写在原函数的上面一行

3、运行原函数fun()

下面我们看看,装饰器的几种结构

最基本的结构就像我们刚才那样,没有参数,没有返回,

def fun1(func): def func_add(): #添加的功能 print('我是镜子,我的功能是供人梳妆打扮用') func() return func_add

带参数的结构

def fun1(func): def func_add(*args,**kwargs): #添加的功能 print('我是镜子,我的功能是供人梳妆打扮用') func(*args,**kwargs) return func_add

我们给厕所加编号,编号采用参数传入,毕竟我买的厕所可是有门牌号的

def fun1(func): def func_add(*args,**kwargs): print('我是镜子,我的功能是供人梳妆打扮用') func(*args,**kwargs) return func_add@fun1def fun(i): print('我是厕所 {} 号,我的功能是让人们大小便'.format(i))fun(10)# 我是镜子,我的功能是供人梳妆打扮用# 我是厕所 10 号,我的功能是让人们大小便

带返回值

def fun1(func): def func_add(*args,**kwargs): #添加的功能 print('我是镜子,我的功能是供人梳妆打扮用') func(*args,**kwargs) a = '金子' return a return func_add

我让我的厕所自动赚钱,毕竟这是一个成熟的厕所

def fun1(func): def func_add(*args,**kwargs): #添加的功能 print('我是镜子,我的功能是供人梳妆打扮用') func(*args,**kwargs) a = '金子' return a return func_add@fun1def fun(i): print('我是厕所 {} 号,我的功能是让人们大小便'.format(i))a = fun(10)print('得到了:',a)# 我是镜子,我的功能是供人梳妆打扮用# 我是厕所 10 号,我的功能是让人们大小便# 得到了:金子

基本的框架结构,就差不多了,我们总结一下

1、装饰器本质就是函数 功能是为其它的函数添加功能

2、原则是1,不改变修饰函数的源代码 2, 不修改修饰函数的调用方式

3、传入参数我们尽量使用可变参数,毕竟你如果你不清楚原函数的参数情况那就麻烦了,当然也可以使用固定参数,

二、偏函数

Python的functools(reduce函数也来源于这个模块)模块提供了很多有用的功能,其中一个就是偏函数(Partial function)。要注意,这里的偏函数不等于数学意义上的偏函数

在介绍函数参数的时候,我们讲到,通过设定参数的默认值,可以降低函数调用的难度。而偏函数也可以做到这一点。举例如下:

偏函数在这里起到一个辅助的作用

我们以 int()为例

>>> int('123456')

123456

其实int 还可以转换进制,

但int()函数还提供额外的base参数,默认值为10。如果传入base参数,就可以做N进制的转换:

>>> int('12345', base=8)

5349

>>> int('456', base=8)

302

但是每次让我们这样传入base 有点麻烦

可以自己写一个函数

def int8(string): return int(string, base=8)print(int8('84569'))#302

>> import functools

>>>int2=functools.partial(int,base=2)

>>>int2('1000000') #64

>>> int2('1010101') #85

这里,我们应该清楚,这里int是指传入二进制的字符串转换成十进制,并不是base=2,就将传入的字符串转换成二进制。

import functoolsmin5 = functools.partial(min, 5)print('min',min(6,55,6))print('min5',min5(6,55,6))min 6min5 5

这里,是将5 自动加了进去,也就是说,如果最小值小于5,就输出最小值,大于5,则返回5,

小结

当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。而被称之为神器的装饰器,说白了就是为了实现这类功能而存在的。希望今天的文章可以为你带来帮助。

分享到: 编辑:环球网校

资料下载 精选课程 老师直播 真题练习

python资格查询

python历年真题下载 更多

python每日一练 打卡日历

0
累计打卡
0
打卡人数
去打卡

预计用时3分钟

python各地入口
环球网校移动课堂APP 直播、听课。职达未来!

安卓版

下载

iPhone版

下载

返回顶部