python基础5之装饰器
内容概要: python解释器从上往下顺序解释代码,碰到函数的定义代码块不会立即执行它,而是将其放在内存中,等到该函数被调用时,才执行其内部的代码块。 2.函数即“变量”: 函数的使用分为,函数的定义和函数的调用,调用方式是为函数名后加括号(函数名存放的是内存地址)类似于变量的使用(先定义,后使用)。可以用一个很形象的列子比喻,函数体相当于一个房间里的工具,函数名相当于门牌号(内存地址)。 示列:
( acl=test
(acl,test)
acl()
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()
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==((=( =>>>>
?解释说明:装饰器带参数,原理是在原来的装饰函数基础之上又封装了一层函数,这层函数作用是为了接收参数(当然,参数可以是函数),用于后面的处理。 ? ? ? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |