zoukankan      html  css  js  c++  java
  • 《流畅的 Python》第 7 章笔记

    装饰器的内容,之前在 Java 中也遇到过,当时只是懵懵懂懂,一方面是当时自己的水平有限,另一方面,当初的学习资料的讲解也不是那么好。而这本书中的第 7 章这一章,讲装饰器可以说是讲得相当好。大部分内容都是通俗易懂,只有最后一点地方需要小小琢磨一下。

    关于装饰器,有几个名词要注意:

    • 装饰器函数,返回被装饰的函数或者经过装饰的函数。如果返回的是被装饰的函数,那么,装饰的效果只会在注册装饰器的时候体现,而如果返回的是经过装饰的函数,那么,装饰的效果会在每一次调用该函数时体现。
    • 装饰器工厂函数,返回装饰器。顾名思义,其实就是生产装饰器的函数。
    registry = set()
    def register(active=True): # ①
        def decorate(func): # ②
            print('running register(active=%s)->decorate(%s)'%(active, func))
            if active:
                registry.add(func)
            else:
                registry.discard(func)
            return func
        return decorate
    @register(active=False)
    def f1():
        print('running f1()')
    @register()
    def f2():
        print('running f2()')
    def f3():
        print('running f3()')
    
    if __name__ == '__main__':
        f1()
        f2()
        f3()
        f1()
        f2()
        f3()
    
    # output
    """
    running register(active=False)->decorate(<function f1 at 0x000001B4F95DB3A0>)
    running register(active=True)->decorate(<function f2 at 0x000001B4F95DB310>)
    running f1()
    running f2()
    running f3()
    running f1()
    running f2()
    running f3()
    """
    

    ① register() 是装饰器工厂函数。
    ② decorate() 是装饰器函数,在这里,其返回的是被装饰的函数本身。

    import time
    DEFAULT_FMT = '[{elapsed:0.8f}s] {name}({args})-> {result}'
    def clock(fmt=DEFAULT_FMT): # ①
        def decorate(func): # ②
            def clocked(*_args):
                t0 = time.time()
                _result = func(*_args)
                elapsed = time.time() - t0
                name = func.__name__
                args = ', '.join(repr(arg) for arg in _args)
                result = repr(_result)
                print(fmt.format(**locals())) # 返回当前作用域的变量字典,解包之后,名字对不上的应该直接被函数舍去了
                return _result
            return clocked
        return decorate
    if __name__ == '__main__':
        @clock()
        def snooze(seconds):
            time.sleep(seconds)
        for i in range(3):
            snooze(.123)
    
    # output
    """
    [0.12360787s] snooze(0.123)-> None
    [0.12413502s] snooze(0.123)-> None
    [0.12307119s] snooze(0.123)-> None
    """
    

    ① clock() 是装饰器工厂函数。
    ② decorate() 是装饰器函数。其返回值是经过修饰的函数。

  • 相关阅读:
    关于宿命论的一点杂想
    关于平权意识
    《天语物道:李政道评传》
    这段时间的杂想
    Spring-Cloud简易全家桶实践
    spring-boot-starter实践
    docker 本地环境安装流程和基本指令
    SpringBoot启动关键点解析 及启动日志追溯
    Bean加载机制解读
    Spring Boot 启动机制源码阅读(粗略)
  • 原文地址:https://www.cnblogs.com/fanlumaster/p/14454583.html
Copyright © 2011-2022 走看看