zoukankan      html  css  js  c++  java
  • 装饰器-记录

    1. 不带参数的装饰器 调用G() 等价于 G = E(G)

    def E(func):
        def F():
            print('这里时F函数里面')
            return func()
        return F
    
    @E
    def G():
        print('执行了G函数')
    
    G()

    2. 带参数的装饰器 ,其实就是最外层给传递参数用,里面还是一个闭包

    调用C() 等价于 C = A(text) (C)

    def A(text):
        def B(func):
            def wrapped():
                print('text 参数 = %s'%text)
                return func()
            return wrapped
        return B
    
    @A('我如黎明中的花朵')
    def C():
        print('执行了C函数')
    
    C()

    3. 装饰有返回值的函数

    def N(functionname):
        print('---N----')
        def func_in():
            print('---func_in---1---')
            ret = functionname()
            print('---func_in---2---')
            return ret
    
        print('---func---2---')
        return func_in
    
    @N
    def M():
        print('---test---')
        return '哈哈'
    
    ret = M()
    print('test return value is %s'%ret)

    为什么打印信息是这样? 解释器遇到@N , 就等同于遇到了M = N (M) , 先执行右边的, 顺着 N 函数执行, 返回 的是 func_in 函数的引用, 此时func_in 并没有()

    ---N----
    ---func---2---
    ---func_in---1---
    ---test---
    ---func_in---2---
    test return value is 哈哈



    4. 两个装饰器,@后面必定去寻找函数,没有的话先让下一个装饰器先装饰

    def w1(func):
        print('---正在装饰1 ---')
        def inner():
            print('--- 正在验证权限1 --- ')
            func()
        return inner
    
    def w2(func):
        print('---正在装饰2---')
        def inner():
            print('---正在验证权限2---')
            func()
        return inner
    
    # 只要python解释器执行到了这个代码 那么就会自动进行装饰 而不是等到调用时才装饰的
    
    @w1
    @w2 # f1 = w2(f1)
    def f1():
        print('---f1----')
    
    f1()

     5.类当装饰器

    参考:https://blog.csdn.net/yitiaodashu/article/details/79016590

    类当作装饰器的意义 如果装饰器想实现的功能比较少,那我们用普通的装饰器即可,但如果我们想实现多种功能,会在一个装饰器里写很多代码,显然用普通的装饰器实现起来很费劲,但如果用类装饰器的话,我们可以把各种功能封装在一个个实例方法中,
    然后在__call__方法中调用不同的实例方法。

    (1) 不带参数的类装饰器

    class Test(object):
        def __init__(self, func):
    print('---初始化---')
    print('func name is %s' % func.__name__)
    self.__func = func

    def __call__(self, *args, **kwargs):
    print('这里写装饰器中的功能代码部分')
    self.__func()


    @Test #py解释器执行到这儿的时候 会执行test = Test(test)
    def test():
    print('---test---')


    test()


    # 说明:
    # 1. 当用Test来作装饰器对test函数进行装饰的时候,首先会创建Test的实例对象并且会把test这个函数名当做参数传递到init方法中即在init方法中的属性__func指向了test指向的函数;
    # 2. test指向了用Test创建出来的实例对象;通常来讲,实例对象不能直接() , 但是当类中写了call方法就能()
    # 3. 当在使用test()进行调用时,就相当于让这个对象(),因此会调用这个对象的call方法;
    # 4. 为了能够在call方法中调用原来test指向的函数体,所以在init方法中就需要一个实例属性来保存这个函数体的引用所以才有了self.func = func这句代码,从而在调用__call方法中能够调用到test之前的函数体。




    (2) 带参数的类装饰器

    class Log(object):
    def __init__(self, num):
    self.num = num

    def __call__(self, func):
    self.func = func
    return self.call_func

    def call_func(self, *args, **kwargs):
    print(self.num)
    return self.func(*args, **kwargs)


    @Log(666)
    def test2():
    print('你为何如此优秀')


    test2()




    此文仅为鄙人学习笔记之用,朋友你来了,如有不明白或者建议又或者想给我指点一二,请私信我。liuw_flexi@163.com/QQ群:582039935. 我的gitHub: (学习代码都在gitHub) https://github.com/nwgdegitHub/
  • 相关阅读:
    spingboot项目在windows环境中运行时接收参数及日志中文乱码
    应用node-webkit(NWJS)把BS架构的网址封装成桌面应用
    AndroidStudio离线打包MUI集成JPush极光推送并在java后端管理推送
    AndroidStudio离线打包MUI
    Centos7环境下搭建Nginx+Lua+Redis进行数据存取
    Nginx各项配置的含义
    MyBatis动态批量插入、更新Mysql数据库的通用实现方案
    spring+springMVC+Mybatis架构下采用AbstractRoutingDataSource、atomikos、JTA实现多数据源灵活切换以及分布式事务管理
    《spring boot》8.2章学习时无法正常启动,报“ORA-00942: 表或视图不存在 ”
    Win10系统使用Docker安装oracle并通过Navicat for oracle进行登录
  • 原文地址:https://www.cnblogs.com/liuw-flexi/p/8953459.html
Copyright © 2011-2022 走看看