加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python基础5之装饰器

发布时间:2020-12-16 23:55:42 所属栏目:Python 来源:网络整理
导读:内容概要: 1.python解释函数代码过程: python解释器从上往下顺序解释代码,碰到函数的定义代码块不会立即执行它,而是将其放在内存中,等到该函数被调用时,才执行其内部的代码块。 2.函数即“变量”: 函数的使用分为,函数的定义和函数的调用,调用方式是

内容概要:

1.python解释函数代码过程:

python解释器从上往下顺序解释代码,碰到函数的定义代码块不会立即执行它,而是将其放在内存中,等到该函数被调用时,才执行其内部的代码块。

2.函数即“变量”:

函数的使用分为,函数的定义和函数的调用,调用方式是为函数名后加括号(函数名存放的是内存地址)类似于变量的使用(先定义,后使用)。可以用一个很形象的列子比喻,函数体相当于一个房间里的工具,函数名相当于门牌号(内存地址)。

示列:

( acl=test (acl,test) acl() this test

3.变量的回收机制:

前面说过函数即变量,当变量的引用阶数为0的时候,其变量的内存才会被回收,并且我们使用del删除的时候只是删除了变量的指向地址,实际变量的值的内存是python定时回收的。tips:变量的阶就是变量被引用的次数,例如x=1,阶就是1,若此时y=x,阶数就是2.

( bar() ( ( ( test() this this bar

?4.函数的嵌套:

函数的嵌套就是在一个函数中定义一个或者多个函数,并且嵌套的函数只能在内层调用,函数外部不能直接调用。

示列:

( ( this outer ( ( inner() this this inner

5.高阶函数

满足两个规则之一:

a.把一个函数名当作实参传递给另外一个函数;

b.返回值中包含函数名;

示例:

test(fun): ( ( ( fun ( a= a() the bar

6.装饰器

定义:本质是函数,作用给其他函数添加附加功能

原则:a.不能修改被装饰函数的源代码

? ? ? ? b.不能修改被装饰函数的调用方式

实现装饰器的步骤:高阶函数+嵌套函数-->装饰器

装饰器使用场景:

公司的网站以前是没有认证功能的,现在产品经理需要你在除了首页以外的地方都加上认证功能,要求不能修改源代码。

假如公司的网站网站如下:

( ( ( person(

装饰器解决方案:

Username= passwd= deco(): username=input(>: password=input(>: username==Username password==passwd: exit( deco @auth ( ( ( plese input your username>> plese input your password>> 个人板块

实现过程:

1.正如上面所说,装饰器的实现需要高阶函数+嵌套函数,那么我们一步一步来看怎么样实现的:

第一步:满足要求一,利用return不改变其源代码的调用方式,把封闭的内层函数地址返回出来,可以供外部调用。

username=input(>: password=input(>: username==Username password== exit( deco ( person=deco(person) person() plese input your username>> plese input your password>> invaild username passwd!

第二步:满足要求二,利用嵌套函数。

deco(): username=input(>: password=input(>: username==Username password== exit( deco ( person=auth(person) person() plese input your username>> plese input your password>> 个人板块

?第三步:关于语法糖@

python中有很多优化语法,例如在我前面代码中使用的@,相当与在这里执行了person=auth(person),此时相当于调用了已经调用了auth函数,将deco函数对象返回给person。

这个语法是死的,这里的语法为:

( username=input(>: password=input(>: username==Username password== exit( @auth ( the auth plese input your username>> plese input your password>> 个人板块

<table style="height: 30px; width: 1132px; background-color: #afeeee; ; width: 1132px;" border="0">

<tr>
<td><span style="font-size: 16px;">二、装饰器</td>
</tr></table>

deco(*args,**kwargs): username=input(>: password=input(>: username==Username password== fun(*args,** exit( (% person( plese input your username>> plese input your password>> wd的个人板块

装饰器内部原理:

内部原理我们可以从上面的代码解释说明:

1.python解释器从上往下解释运行代码,到读到def auth(fun)的时候,解释器发现它是一个函数,于是将函数体加载在内存中,然后跳过到达@auth

2.解释器读取@auth发现是个装饰函数,此时相当于解释到person=auth(person),此时已经调用函数auth,并且执行函数体,发现def deco(*args,**kwargs)又是一个函数,于是将函数体加载到内存,接着跳到return deco,此时将deco函数的内存地址赋值给你person,经过这个步骤,person变量的内存地址指向了deco,下面调用person相当于调用deco。

3.解释器解释到person(),此时的person的内存地址是指向deco的,调用person就是调用deco,然后执行deco的函数体,执行deco的函数体就加了认证功能,并且在执行此时person,这样就完美的把需求实现了。

有些人可能会问,为什么需要在外部包装一层函数?

答案是:如果不再外部包装一层装饰函数,当我们使用装饰器时直接就执行了该函数,此时我们都还没有调用,然后程序已经执行了,这显然不是我们所要的。

例子:

( ( 结果: the test

<table style="height: 30px; width: 1132px; background-color: #afeeee; ; width: 1132px;" border="0">

<tr>
<td><span style="font-size: 16px;">三、装饰器高潮版</td>
</tr></table>

先观察下面例子,如果按照原来的方法,代码执行完,被修饰函数的返回值丢了;

(( =

那么怎么样才能接收到这个返回值呢,很容易,使用变量接收fun的返回值,并将其在deco函数中return出来,请看下面代码;

(=fun() res ( =

<table style="height: 30px; width: 1132px; background-color: #afeeee; ; width: 1132px;" border="0">

<tr>
<td><span style="font-size: 16px;">四、装饰器之最终高潮版--带参数的装饰器</td>
</tr></table>

username== logger(type): auth(fun): deco(*args,**kwargs): ( type===input(>= input(> _username==username _passwd==(= fun(*args,** ( type==((=( =>>>>

?解释说明:装饰器带参数,原理是在原来的装饰函数基础之上又封装了一层函数,这层函数作用是为了接收参数(当然,参数可以是函数),用于后面的处理。

? ? ? ??

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!