• 学习笔记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'}
     ********************************************************************************************************************************************
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    Git clone The requested URL returned error: 403 错误
    创建DOTA2本地数据库(一)
    如何打开VPK文件?里面究竟有什么?
    DOTA 2 API(个人资料)
    新的博客,新的开始!
    你应该在开始API开发之前知道的事(下)(翻译)
    你应该在开始API开发之前知道的事(上)(翻译)
    DOTA 2 Match History WebAPI(翻译)
    C#中UnixTime和DateTime的转换(转载)
    搜查令中期总结
  • 原文地址:https://www.cnblogs.com/pylblog/p/8270513.html
Copyright © 2020-2023  润新知