学习笔记61_装饰器理解

 ***********************************************************************************************************************************

在python中,函数名也是一个变量,

例如:

def  fun1():

  #todo

def fun2()

  #todo

def fun3(b)

      if b: return fun1

    else :return fun2

//

fun1 = fun3(true)

  #这样子,就可以将fun1替换成fun2了

当然,fun1 = fun2也行;

 ************************************************************************************************************************************

基于上述,假如fun1需要登录后才能使用,fun2不需要,那么,只能有如下方式:

1.在调用fun1前,执行一下login,然后在决定要不要执行fun1。(弊端:每个调用fun1的地方都得改)

2.在fun1内,插入login,决定要不要继续下去(弊端:要修改fun1,不符合编程的设计思想)

3.使用fun1 = fun3(true)将fun1在一开始替换掉,做法:

def login(fun1):

  def defineExcuteFun1():#再嵌套一个函数

    hasLogin = #从缓存中查看有没有登录

    if hasLogin : fun1()

    else : print("跳转到其他地方")

return defineExcuteFun1

#fun1作为一个参数传到login 中,然后又成为defineExcuteFun1的一部分,那么

fun1 = login(fun1) #那么fun1 就是 defineExcuteFun1

fun2 = login(fun2) #那么fun1 就是 defineExcuteFun1  ,值得注意的是,两个defineExcuteFun1,分别以原来的fun1,原来的fun2作为自己的组成部分(闭包),是不同的。

 

#例子:

def seeMove():

   #todo

seeMove = login(seeMove)

#调用还是一样,就在里头执行defineExcuteFun1(),由里头的逻辑,决定要不要执行最初的seeMove

seeMove()

#如果seeMove是带参数才能执行的话,上面的方式中,在defineExcuteFun1()中,调用的方式是fun1(),是以不带参数的方式来调用的,那么,可以:

 

def login(fun1):

  def defineExcuteFun1(*args):#再嵌套一个函数

    hasLogin = #从缓存中查看有没有登录

    if hasLogin : return fun1(*args)

    else : print("跳转到其他地方")

return defineExcuteFun1

以上这种方式,叫做装饰器,类似于MVC中的action的过滤器,其实就是attribute,由可以将上面  seeMove = login(seeMove)去掉,换成:

@login

def seeMove(a,b):

   #todo

这时,调用seeMove(c,d),如果在登录状态下,实质是 login(seeMove(c,d))这样。

 ****************************************************************************************************************************************************************

 #如果还有一个需要,这个seeMove不仅仅要login,而且要规定 某个身份特征的人,才能使用,那么

def alogin(Authority):

  def  login(fun1):

    def defineExcuteFun1(*args):#再嵌套一个函数

      hasLogin = #从缓存中查看有没有登录

      isAuthority =  #读出的authority is  Authority  //Authority又一次作为函数的元素了

      if hasLogin and isAuthority :retrun  fun1(*args)

      else : print("跳转到其他地方"

   return defineExcuteFun1

 return  login

 

@alogin("超级管理员")

def seeMove(a,b):

  #todo

 

 注意:这里跟上面 seeMove = login(seeMove)不一样了,这里def alogin(Authority)如果按上面套路走,起码要fun1这个形参,这里则没有了

 也就说明,fun1这个形参被省了

那么,上面,其实还是  seeMove = login(seeMove) ,alogin 则是负责将 参数带到去最内边使用而已。

猜想, @alogin("超级管理员")的 结果,可以当做是执行了一条函数,其实就是将 " @Login“返回来,给seeMove做装饰器

@alogin("xxxx") 带参 和 @login  不带参是不同的,  前者是“返回装饰器”,然后装饰,后者是“装饰器”,直接装饰

*****************************************************************************************************************************************************************

(知识补充)非固定参数

若你的函数在定义时不确定用户想传入多少个参数,就可以使用非固定参数

def stu_register(name,age,*args): # *args 会把多传入的参数变成一个元组形式
    print(name,age,args)
 
stu_register("Alex",22)
#输出
#Alex 22 () #后面这个()就是args,只是因为没传值,所以为空
 
stu_register("Jack",32,"CN","Python")
#输出
# Jack 32 ('CN', 'Python')
def stu_register(name,age,*args,**kwargs): # *kwargs 会把多传入的参数变成一个dict形式
    print(name,age,args,kwargs)
 
stu_register("Alex",22)
#输出
#Alex 22 () {}#后面这个{}就是kwargs,只是因为没传值,所以为空
 
stu_register("Jack",32,"CN","Python",sex="Male",province="ShanDong")
#输出
# Jack 32 ('CN', 'Python') {'province': 'ShanDong', 'sex': 'Male'}
 ********************************************************************************************************************************************
 
 
 
 
 
 
 
 
 

posted on   耀礼士多德  阅读(134)  评论(0编辑  收藏  举报

(评论功能已被禁用)
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示