• Python3-装饰器


    装饰器(语法糖)

    装饰器的本质:一个闭包函数

    装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

    例子1.

    给hahaha函数加上一个timmer(计算函数执行时间)的功能。

    import time
    def timmer(func):
        #函数名可以当做函数的参数
        def inner():
            start = time.time()
            func()
            end = time.time()
            print(start - end)
        return inner
    
    # 语法糖
    @timmer       # @把hahaha函数名作为参数传到timmer(),执行了一次, 然后进行了重新赋值 hahaha = timmer(hahaha) --> inner()
    def hahaha():
        time.sleep(0.1)
        print('aaaa')
    
    # time(hahaha)      不能改变这个函数的调用方式
    # 也不能修改源代码
    # hahaha = timmer(hahaha)       timmer(hahaha)函数的执行结果返回 inner函数的内存地址,然后赋值给hahaha
    # hahaha()  就等同于  inner()
    
    hahaha()

    装饰器的设计模式:开放封闭原则

    开放:对扩展是开放的

    封闭:对修改是封闭的

    刚刚我们讨论的装饰器都是装饰不带参数的函数,现在要装饰一个带参数的函数怎么办?

    import time
    
    def timer(func):
        def inner(*args, **kwargs):
            start_time = time.time()
            func(*args, **kwargs)
            end_time = time.time()
            print(end_time - start_time)
        return inner
    
    @timer
    def func1(a):
        time.sleep(2)
        print(a)
    
    func1('bb')

    带参数的装饰器

    def outer(flag):
        def timer(func):
            def inner(*args, **kwargs):
                if flag:
                    print('执行函数之前要做的')
                func(*args, **kwargs)
                if flag:
                    print('执行函数之后要做的')
            return inner
        return timer
    
    @outer(True)
    def func2(mode):
        print(111, mode)
    
    func2('rrr')

    多个装饰器装饰同一个函数

    有些时候,我们也会用到多个装饰器装饰同一个函数的情况。

    单个装饰器:

    
    
    def first(func):
    print('%s() was post to first()' % func.__name__)
    def _first(*args, **kwargs):
    print('Call the function %s() in _first().' % func.__name__)
    return func(*args, **kwargs)
    return _first

    @first # first(test) test = first(test) --> _first
    def test():
    return 'hello world!'

    test()

    输出:

    test() was post to first()
    Call the function test() in _first().

     多重装饰器:

    def first(func):
        print('%s() in first' % func.__name__)
        def _first(*args, **kwargs):
            print('Call the function %s() in _first().' % func.__name__)
            return func(*args, **kwargs)
        return _first
    
    def second(func):
        print('%s() in second()' % func.__name__)
        def _second(*args, **kwargs):
            print('Call the function %s() in _second().' % func.__name__)
            return func(*args, **kwargs)
        return _second
    
    
    @first      # first(test)  test = first(test) --> _first
    @second     # second(test) test = second(test) --> _second
    def test():
        return 'hello world!'
    
    test()

    输出:

    test() was post to second()
    _second() was post to first()
    Call the function _second() in _first().
    Call the function test() in _second().

    实际上它是相当于下面的代码:

    >>> def test():
        return 'hello world'
    
    >>> test=second(test)
    test() was post to second()
    >>> test
    <function _second at 0x000000000316D3C8>
    >>> test=first(test)
    _second() was post to first()
    >>> test
    <function _first at 0x000000000316D358>
    >>> test()
    Call the function _second() in _first().
    Call the function test() in _second().
    'hello world'
    >>>
  • 相关阅读:
    ROM、RAM、DRAM、SRAM和FLASH的区别
    寄存器读写为什么需要用位操作符
    不同变量存放在什么地方
    C语言中数据类型对变量的作用
    内存寻址、对齐,变量左值和右值
    位、字节、半字、字、内存位宽
    面试题10- II. 青蛙跳台阶问题
    509. 斐波那契数
    面试题10- I. 斐波那契数列
    面试题32
  • 原文地址:https://www.cnblogs.com/Xuuuuuu/p/10178392.html
Copyright © 2020-2023  润新知