zoukankan      html  css  js  c++  java
  • 装饰器

    # 首先介绍闭包(理解闭包是理解装饰器的前提)
    # 什么是闭包呢?在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包
    def test01(num):
        def test02():
            print("num is %d" % num)
    
        return test02
    
    
    ret = test01(20)
    ret()
    print("*" * 60)
    
    
    # 装饰器的理解
    # 需求:在不更改源代码的情况下,对原来的方法添加一些验证。比如:flag==1 才执行 test01()等等
    # 装饰器的应用场景:
    # 1、引入日志
    # 2、函数执行时间统计(这个可以常用啊)
    # 3、执行函数前预备处理
    # 4、执行函数后清理功能
    # 5、权限校验等场景
    # 6、缓存
    
    # 无参数的装饰器
    def test03(func):
        print("-----1-----")
    
        def test04():
            print("-----2-----")
            func()
    
        return test04
    
    
    # @test03 等价于下面这两句话
    # test05 = test03(test05)
    # test05()
    @test03
    def test05():
        print("-----3-----")
    
    
    test05()
    print("*" * 60)
    
    
    # 注意:装饰的函数是带参函数时,返回的test07()也必须是代参函数,用来接收
    # 被装饰的函数有参数
    def test06(func):
        print("-----1-----")
    
        def test07(name, age):
            print("-----2-----")
            func(name, age)
    
        return test07
    
    
    @test06
    def test08(name, age):
        print("-----3-----")
        print("name is %s, %d" % (name, age))
    
    
    test08("张三", 15)
    print("*" * 60)
    
    
    # 通用的装饰器函数,不论它是有参还是无参,有返回值还是无返回值,都是通用的
    # args——存放元组参数,前面有一个*
    # kwargs——存放字典参数,前面有两个*
    # 补充:元组和字典的拆包:如果希望将一个元组或者字典直接传给函数,可在参数名前面加一个*或者两个*
    def test09(func):
        print("-----1-----")
    
        def test10(*args, **kwargs):
            print("-----2-----")
            ret = func(*args, **kwargs)
            return ret
    
        return test10
    
    
    @test09
    def test11(*args, **kwargs):
        print("-----3-----")
        return args, kwargs
    
    
    print(test11(*("腾讯", "阿里巴巴", "谷歌"), **{"张三": 15, "李四": 16, "王五": 17}))
    print("*" * 60)
    
    
    # 两个装饰器,首先看到第一个@test12,但是呢?发现下面还有一个@test14,而装饰器是用来装饰函数的,不能用来装饰@test14
    # 所以要等下面的@test14装饰完了之后,@test12才能再装饰
    # 两个装饰器(理解)
    def test12(func):
        print("-----1-----")
    
        def test13():
            print("-----2-----")
            return "hello " + func()
    
        return test13
    
    
    def test14(func):
        print("-----3-----")
    
        def test15():
            print("-----4-----")
            return "python " + func()
    
        return test15
    
    
    @test12
    @test14
    def test16():
        print("-----5-----")
        return "world"
    
    
    print(test16())
    print("*" * 60)
    
    
    # 1、因为装饰器带了参数,首先是直接调用timefun_arg(),返回了timefun,此时的@timefun_arg("itcast")就变成了@timefun
    # 2、然后才装饰foo()函数
    # 3、后面的步骤如上
    def test17(str="hello"):
        def test18(func):
            def test19():
                print("%s" % str)
                return func()
    
            return test19
    
        print(str)
        return test18
    
    
    @test17("hello world")
    def test20():
        print("this is python world")
    
    
    test20()
    print("*" * 60)
    
    
    # 类装饰器(了解)
    # 要想理解类装饰器,首先需要理解下面这段代码
    class test21(object):
        def __call__(self):
            print('call me!')
    
    
    t = test21()
    t()
    # t是一个对象,又不是一个方法,怎么可以t()呢?
    # 原来t()会默认调用__call__(self)方法,因为类test21重写了__call__(self)方法,所以调用重写后的
    print("*" * 60)
    
    
    # 接下来才是类装饰器(不得不说动态语言真是花里胡哨)
    class test22(object):
        def __init__(self, func):
            print("---初始化---")
            print("func name is %s" % func.__name__)
            self.__func = func
    
        def __call__(self):
            print("---装饰器中的功能---")
            self.__func()
    
    
    @test22
    def test():
        print("----test---")
    
    
    test()
  • 相关阅读:
    Android压缩图片到100K以下并保持不失真的高效方法
    Android 动画学习笔记
    JAVA jdbc连接Mysql
    android 在myeclipse中查看源码
    Intent用法总结
    Android中加载数据库到data/data下的当前包中
    Android Paint类介绍
    经典常用SQL语句大全
    android 语音识别技术
    Insert multi user or more than one user in SharePoint list Person or Group field
  • 原文地址:https://www.cnblogs.com/tangxlblog/p/9948249.html
Copyright © 2011-2022 走看看