栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Fluent Python | 函数装饰器

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Fluent Python | 函数装饰器

写在前面:Fluent Python 系列是学习《Fluent Python》的笔记 ~

这是一本适合Python进阶的书,不仅有一些高级语法,作者对部分底层实现也有讲解,以便于我们理解Python的设计,比如为什么普通字典是无序的呢?

函数装饰器
        • 1 变量作用域
        • 2 闭包
        • 3 装饰器
          • 3.1 基本概念和写法
          • 3.2 装饰器何时执行
          • 3.3 标准库中常用的两个装饰器函数
          • 3.4 参数化装饰器
        • 4 小结

1 变量作用域

注意函数体内赋值的局部变量与函数体外同名全局变量


 

 

2 闭包

 

 

3 装饰器 3.1 基本概念和写法

 
import time
from clockedeco import clock
from functools import lru_cache


@clock
def snooze(seconds):
    time.sleep(seconds)

    
    
#@clock    
#def factorial(n):
#    return 1 if n < 2 else factorial(n-1)

def factorial(n):
    return 1 if n < 2 else factorial(n-1)
factorial = clock(factorial)

@lru_cache()
@clock
def fibonacci(n):
    if n < 2 :
        return n
    else:
        return fibonacci(n-2) + fibonacci(n-1)

if __name__ == '__main__':
#    print('*' * 40, 'Calling snooze(.123)')
#    snooze(.123)                                # 此时调用的已经是被装饰过的函数
#    print('*' * 40, 'Calling factorial(6)')
#    print('6!=', factorial(6))
    print(fibonacci(6))

 

3.2 装饰器何时执行

 
registry = []

# 定义装饰器
def register(func):
    print('running register(%s)' % func)
    registry.append(func)
    return func

# 定义被装饰的函数
@register
def f1():
    print('running f1()')

def f3():
    print('runing f3()')

def main():
    print('running main()')
    print('registry->', registry)
    f1()    # 调用被装饰的函数
    f3()

if __name__ == '__main__':
    main()

 

3.3 标准库中常用的两个装饰器函数

 
from functools import singledispatch
from collections import abc
import numbers
import html

@singledispatch
def htmlize(obj):
    """处理Object类型的基函数"""
    content = html.escape(repr(obj))
    return '
{}
'.format(content) # 以下各个专门函数使用@《base_function》.register()装饰 @htmlize.register(str) def _(text): # 专门函数的名称无关紧要 content = html.escape(text).replace('n', '
n') return '

{0}

'.format(content) @htmlize.register(numbers.Integral) def _(n): return '
{0} (0x{0:x})
'.format(n) @htmlize.register(tuple) @htmlize.register(abc.MutableSequence) def _(seq): inner = 'n
  • '.join(htmlize(item) for item in seq) return '
      n
    • ' + inner + '
    • n
    '
  •  

    3.4 参数化装饰器

      4 小结

    我所用到的函数装饰器的场景:

    1. 优化递归函数:跟书中介绍的例子相同,斐波那契数列有一种解法便称之为“备忘录”,就是将已经计算出的结果保存在数组中,eg:保存f(1), f(2),这样在计算f(3)=f(1)+f(2)的时候就不需要再重复计算f(1)和f(2),只需要在数组中查找即可。Python内嵌的装饰器实现了备忘录的功能,不需要手动再设置数组保存结果,直接使用@lru_cache装饰器即可。

      https://leetcode-cn.com/problems/fibonacci-number/

    2.使用Python实现类似C++/Java 函数重载的功能
    Python确实没有函数重载,遇到针对不同情况调用不同函数的时候,最简单的方法就是使用if-elif-else分别调用专门的函数,这种做法的扩展性确实不好。

    转载请注明:文章转载自 www.mshxw.com
    本文地址:https://www.mshxw.com/it/323422.html
    我们一直用心在做
    关于我们 文章归档 网站地图 联系我们

    版权所有 (c)2021-2022 MSHXW.COM

    ICP备案号:晋ICP备2021003244-6号