Python入门篇-functools

                                      作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.reduce方法

  reduce方法,顾名思义就是减少

  reduce(function,sequence[,initial])->value

  可迭代对象不能位空;初始值没提供就在可迭代对象中取一个元素
 #!/usr/bin/env python
#_*_conding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie from functools import reduce print(reduce(lambda x,y:x*y,range(1,6))) #我们可以用来计算5的阶乘
print(reduce(lambda x,y:x*y,range(1,6),100)) #当然,我们也可以指定函数的起始值,这个起始值会直接赋值给x变量,如果没有指定则会使用序列的第一个数字来赋初值。 nums = [6,9,4,2,4,10,5,9,6,9]
print(nums)
print(sum(nums))
print(reduce(lambda x,y:x+y,nums)) #以上代码输出结果如下:
120
12000
[6, 9, 4, 2, 4, 10, 5, 9, 6, 9]
64
64

二.partial方法

1>.partial概述

  偏函数,把函数部分的参数固定下来,相当于为部分的参数添加了一个固定的默认值,形成一个新的函数并返回
  
  从partial生成的新函数,是对原函数的封装

2>.partial方法举例

 #!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com import functools,inspect def add(x, y, *args) -> int:
print("add args:{}".format(args))
return x + y newadd = functools.partial(add, y=5) print(inspect.signature(add))
print(newadd(7))
print(newadd(10, y=20))
print(newadd(y=10, x=6))
print(inspect.signature(newadd)) #以上代码执行结果如下:
(x, y, *args) -> int
add args:()
12
add args:()
30
add args:()
16
(x, *, y=5) -> int
 #!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com import functools,inspect def add(x, y, *args) -> int:
print("add args:{}".format(args))
return x + y newadd = functools.partial(add, 1,3,6,5)
print(newadd(7))
print(newadd(7, 10))
print(newadd())
print(inspect.signature(add))
print(inspect.signature(newadd)) #以上代码执行结果如下:
add args:(6, 5, 7)
4
add args:(6, 5, 7, 10)
4
add args:(6, 5)
4
(x, y, *args) -> int
(*args) -> int

partial方法举例

3>.partial函数本质

def partial(func, *args, **keywords):
  def newfunc(*fargs, **fkeywords): # 包装函数
    newkeywords = keywords.copy()
    newkeywords.update(fkeywords)
    return func(*(args + fargs), **newkeywords)
  newfunc.func = func # 保留原函数
  newfunc.args = args # 保留原函数的位置参数
  newfunc.keywords = keywords # 保留原函数的关键字参数参数
  return newfunc def add(x,y):
  return x+y

foo = partial(add,4)
foo(5)

二.lru_cache方法

1>.lru_cache概述

@functools.lru_cache(maxsize=128, typed=False)
  Least-recently-used装饰器。lru,最近最少使用。cache缓存
  如果maxsize设置为None,则禁用LRU功能,并且缓存可以无限制增长。当maxsize是二的幂时,LRU功能执行得最好
  如果typed设置为True,则不同类型的函数参数将单独缓存。例如,f(3)和f(3.0)将被视为具有不同结果的不同调用

2>. lru_cache举例

 #!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com import functools
import time @functools.lru_cache()
def add(x, y, z=3):
time.sleep(z)
return x + y print(add(4, 5))
print(add(4.0, 5))
print(add(4, 6))
print(add(4, 6, 3))
print(add(3, 2))
print(add(2, y=3))
print(add(x=40, y=60))
print(add(y=60, x=40))

3>.lru_cache装饰器

  通过一个字典缓存被装饰函数的调用和返回值
  key是什么?分析代码看看
    functools._make_key((4,6),{'z':3},False)
    functools._make_key((4,6,3),{},False)
    functools._make_key(tuple(),{'z':3,'x':4,'y':6},False)
    functools._make_key(tuple(),{'z':3,'x':4,'y':6}, True)
 #!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com import functools @functools.lru_cache() # maxsize=None
def fib(n):
if n < 3:
return n
return fib(n-1) + fib(n-2) print([fib(x) for x in range(35)]) #以上代码执行结果如下:
[0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465]

斐波那契数列递归方法的改造

4>.lru_cache装饰器应用

  使用前提
    同样的函数参数一定得到同样的结果
    函数执行时间很长,且要多次执行

  本质是函数调用的参数=>返回值
 
  缺点
    不支持缓存过期,key无法过期、失效
    不支持清除操作
    不支持分布式,是一个单机的缓存
  
  适用场景,单机上需要空间换时间的地方,可以用缓存来将计算变成快速的查询

三.装饰器应用练习

1>.实现一个cache装饰器,实现可过期被清除的功能

  简化设计,函数的形参定义不包含可变位置参数、可变关键词参数和keyword-only参数
  
  可以不考虑缓存满了之后的换出问题

2>.写一个命令分发器

  程序员可以方便的注册函数到某一个命令,用户输入命令时,路由到注册的函数
  如果此命令没有对应的注册函数,执行默认函数

  用户输入用input(">>")

Python入门篇-functools的更多相关文章

  1. Python入门篇-装饰器

    Python入门篇-装饰器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.装饰器概述 装饰器(无参) 它是一个函数 函数作为它的形参 返回值也是一个函数 可以使用@functi ...

  2. Python入门篇-面向对象概述

    Python入门篇-面向对象概述 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.语言的分类 面向机器 抽象成机器指令,机器容易理解 代表:汇编语言 面向过程 做一件事情,排出个 ...

  3. Python入门篇-StringIO和BytesIO

    Python入门篇-StringIO和BytesIO 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.StringIO(用于文本处理) 1>.使用案例 #!/usr/bin ...

  4. Python入门篇-文件操作

    Python入门篇-文件操作 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.文件IO常用操作 open:打开 read:读取 write:写入 close:关闭 readlin ...

  5. Python入门篇-类型注解

    Python入门篇-类型注解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.函数定义的弊端 1>.动态语言很灵活,但是这种特性也是弊端 Python是动态语言,变量随时可 ...

  6. Python入门篇-数据结构堆排序Heap Sort

    Python入门篇-数据结构堆排序Heap Sort 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.堆Heap 堆是一个完全二叉树 每个非叶子结点都要大于或者等于其左右孩子结点 ...

  7. Python入门篇-数据结构树(tree)的遍历

    Python入门篇-数据结构树(tree)的遍历 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.遍历 迭代所有元素一遍. 二.树的遍历 对树中所有元素不重复地访问一遍,也称作扫 ...

  8. Python入门篇-高阶函数

    Python入门篇-高阶函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.高级函数  1>.First Class Object 函数在Python中是一等公民 函数也 ...

  9. Python入门篇-生成器函数

    Python入门篇-生成器函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.生成器概述 1>.生成器generator 生成器指的是生成器对象,可以由生成器表达式得到, ...

随机推荐

  1. 媲美GWAS Catalog,囊括45万人数据,778个表型,3千万个位点的公共数据库:GeneATLAS

    欢迎关注微信公众号"bio生物信息" GeneATLAS的数据全部来自 UK Biobank 的452,264个英国白人样本. 总共囊括的表型有778个,位点有三千万个. 优点 网 ...

  2. windows下tomcat日志的坑

    最近在调试工程,想着在windows下多开窗口操作方便,结果发现日志竟然不全,百思不得其解.最后发现竟然是部署的坑. 之前的部署都是在bin目录下运行service.bat安装服务后了事,启停都通过t ...

  3. Java之输入和输出

    输出 在前面的代码中,我们总是用System.out.println()来向屏幕输出一些内容: println是print line的缩写,表示输出并换行.因此,如果输出后不想换行,可以用print( ...

  4. Gerrit - 初始配置

    1 - 插件管理 1.1 下载并安装插件 以reviewers插件为例. 在GerritForge(https://gerrit-ci.gerritforge.com/),找到对应gerrit 版本的 ...

  5. UE4 常用数学

    转自:https://dawnarc.com/2016/07/mathlinear-algebra%E5%90%91%E9%87%8F%E7%A7%AF%E5%A4%96%E7%A7%AF%E5%8F ...

  6. ThinkPHP3创建Model模型--对表的操作

    创建Model模型 把"Home/Model"文件夹剪切到Application文件夹下,让Home和Admin共同使用. 第一种实例化模型的方法 第二种实例化模型的方法 第三种实 ...

  7. PHP 去一定范围随机小数 随机浮点数

    例如取2到3中的 随机小数(一位)或整数 mt_rand(20,30)/10 mt_rand()是随机取整函数 先扩大一定倍数,再缩小相应倍数,倍数代表精确到哪一位

  8. Python爬虫:现学现用xpath爬取豆瓣音乐

    爬虫的抓取方式有好几种,正则表达式,Lxml(xpath)与BeautifulSoup,我在网上查了一下资料,了解到三者之间的使用难度与性能 三种爬虫方式的对比. 这样一比较我我选择了Lxml(xpa ...

  9. [译] QUIC Wire Layout Specification - Frame Types and Formats | QUIC协议标准中文翻译(4) 帧类型和格式

    欢迎访问我的个人网站获取更好的阅读排版体验: [译] QUIC Wire Layout Specification - Frame Types and Formats | QUIC协议标准中文翻译(4 ...

  10. 使用adb命令对移动设备截图

    步骤: 1)   首先要进入CMD窗口,命令行模式,连接设备. 2)使用screencap 命令,对安卓设备的当前屏幕进行截屏,示例: adb shell screencap -p /sdcard/0 ...