返回顶部
首页 > 资讯 > 后端开发 > Python >记忆(缓存)函数返回值:Python 实
  • 488
分享到

记忆(缓存)函数返回值:Python 实

缓存函数返回值 2023-01-30 22:01:40 488人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

对于经常调用的函数,特别是递归函数或计算密集的函数,记忆(缓存)返回值可以显着提高性能。而在 python 里,可以使用字典来完成。 例子:斐波那契数列 下面这个计算斐波那契数列的函数 fib() 具有记忆功能,对于计算过的函数参数可以直

对于经常调用的函数,特别是递归函数或计算密集的函数,记忆(缓存)返回值可以显着提高性能。而在 python 里,可以使用字典来完成。

例子:斐波那契数列

下面这个计算斐波那契数列的函数 fib() 具有记忆功能,对于计算过的函数参数可以直接给出答案,不必再计算:

fib_memo = {}
def fib(n):
    if n < 2: return 1
    if not n in fib_memo:
        fib_memo[n] = fib(n-1) + fib(n-2)
    return fib_memo[n]

更进一步:包装类

我们可以把这个操作包装成一个类 Memory,这个类的对象都具有记忆功能:

class Memoize:
    """Memoize(fn) - 一个和 fn 返回值相同的可调用对象,但它具有额外的记忆功能。
       只适合参数为不可变对象的函数。
    """
    def __init__(self, fn):
        self.fn = fn
        self.memo = {}
    def __call__(self, *args):
        if not args in self.memo:
            self.memo[args] = self.fn(*args)
        return self.memo[args]

# 原始函数
def fib(n):
    print(f'Calculating fib({n})')
    if n < 2: return 1
    return fib(n-1) + fib(n-2)

# 使用方法
fib = Memoize(fib)

运行测试,计算两次 fib(10)

Calculating fib(10)
Calculating fib(9)
Calculating fib(8)
Calculating fib(7)
Calculating fib(6)
Calculating fib(5)
Calculating fib(4)
Calculating fib(3)
Calculating fib(2)
Calculating fib(1)
Calculating fib(0)
89
89

可以看到第二次直接输出 89,没有经过计算。

再进一步:装饰器

对装饰器熟悉的程序员应该已经想到,这个类可以被当成装饰器使用。在定义 fib() 的时候可以直接这样:

@Memoize
def fib(n):
    if n < 2: return 1
    return fib(n-1) + fib(n-2)

这和之前的代码等价,但是更简洁明了。

最后的完善

之前的 Memory 类只适合包装参数为不可变对象的函数。原因是我们用到了字典作为存储介质,将参数作为字典的 key;而在 Python 中的 dict 只能把不可变对象作为 key 2,例如数字、字符串、元组(里面的元素也得是不可变对象)。所以提高代码通用性,我们只能牺牲运行速度,将函数参数序列化为字符串再作为 key 来存储,如下:

class Memoize:
    """Memoize(fn) - 一个和 fn 返回值相同的可调用对象,但它具有额外的记忆功能。
       此时适合所有函数。
    """
    def __init__(self, fn):
        self.fn = fn
        self.memo = {}
    def __call__(self, *args):
        import pickle
        s = pickle.dumps(args)
        if not s in self.memo:
            self.memo[s] = self.fn(*args)
        return self.memo[s]

使用第三方库 - joblib

除了这种手工制作的方法,有一个第三方库 joblib 能实现同样的功能,而且性能更好,适用性更广。因为上文中的方法是缓存在内存中的,每次都要比较传入的参数。对于很大的对象作为参数,如 numpy 数组,这种方法性能很差。而 joblib.Memory 模块提供了一个存储在硬盘上的 Memory 类,其用法如下:

首先定义缓存目录:

>>> cachedir = 'your_cache_location_directory'

以此缓存目录创建一个 memory 对象:

>>> from joblib import Memory
>>> memory = Memory(cachedir, verbose=0)

使用它和使用装饰器一样:

>>> @memory.cache
... def f(n):
...     print(f'Running f({n})')
...     return x

以同样的参数运行这个函数两次,只有第一次会真正计算:

>>> print(f(1))
Running f(1)
1
>>> print(f(1))
1

参考

1 Http://code.activestate.com/recipes/52201/

2 https://docs.python.org/3/tutorial/datastructures.html#dictionaries

3 https://joblib.readthedocs.io/en/latest/memory.html#use-case

(本文完)

--结束END--

本文标题: 记忆(缓存)函数返回值:Python 实

本文链接: https://lsjlt.com/news/179227.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 记忆(缓存)函数返回值:Python 实
    对于经常调用的函数,特别是递归函数或计算密集的函数,记忆(缓存)返回值可以显着提高性能。而在 Python 里,可以使用字典来完成。 例子:斐波那契数列 下面这个计算斐波那契数列的函数 fib() 具有记忆功能,对于计算过的函数参数可以直...
    99+
    2023-01-30
    缓存 函数 返回值
  • 怎么用Python装饰器来缓存函数的返回值
    本篇内容主要讲解“怎么用Python装饰器来缓存函数的返回值”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用Python装饰器来缓存函数的返回值”吧!Pythonclass Memoized...
    99+
    2023-06-03
  • python函数的返回值
    返回值:return1.没有返回值    #不写return    #只写return:结束一个函数    #return None2.有一个返回值    #可以返回任何数据类型    #只要返回就可以接收到    #如果在一个程序中有多个...
    99+
    2023-01-30
    函数 返回值 python
  • python函数怎么返回多个返回值
    本篇内容主要讲解“python函数怎么返回多个返回值”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“python函数怎么返回多个返回值”吧!一般情况下,函数只有一个返回值,但Python也支持函数...
    99+
    2023-06-30
  • golang函数返回值内存管理
    go 函数返回值通常分配在堆上,导致内存开销。优化方法包括:避免返回大结构,使用值语义,返回指针,使用缓冲池。这些技巧可以减少堆分配,从而优化内存管理和性能。 Go 函数返回值内存管理...
    99+
    2024-04-23
    golang 内存管理
  • python读取oracle函数返回值
    在oracle中创建一个函数,本来是想返回一个index table的,没有成功。想到文本也可以传输信息,就突然来了灵感,把返回值设置文本格式。 考虑到返回数据量可能会很大,varchar2类型长度吃紧,于...
    99+
    2022-06-04
    函数 返回值 python
  • golang函数的返回值实现
    函数可以有0或多个返回值,返回值需要指定数据类型,返回值通过return关键字来指定。 return可以有参数,也可以没有参数,这些返回值可以有名称,也可以没有名称。go中的函数可以...
    99+
    2023-03-08
    golang函数返回值 golang 返回值
  • python怎么获取回调函数返回值
    在Python中,可以使用callback函数来获取回调函数的返回值。以下是一个示例: def callback_function(...
    99+
    2024-02-29
    python
  • 用python读取oracle函数返回值
    在oracle中创建一个函数,本来是想返回一个index table的,没有成功。想到文本也可以传输信息,就突然来了灵感,把返回值设置文本格式。考虑到返回数据量可能会很大,varchar2类型长度吃紧,于是...
    99+
    2024-04-02
  • python如何打印函数返回值
    python中使用print函数打印函数返回值,具体方法如下:print函数:print函数是用于打印函数的返回值。print函数语法:print(*objects, sep=' ', end='\n', file=sys.stdout, ...
    99+
    2024-04-02
  • python中函数返回值是什么
    python中函数的返回值包含指定返回值和隐含返回值两种指定返回值当函数中有return语句时,return语句的结果就是函数的返回值。例:def info(x):return x +1函数返回值为x+1,其中x为函数的参数。隐含返回值如函...
    99+
    2024-04-02
  • python函数如何返回多个值
    一般情况下,一个函数只有一个返回值,Python也是如此,只是Python函数可以通过返回列表或元组的方式将返回的多个值保存到序列中,从而间接达到返回多个值的目的。说明1、将要返回的多个值提前存储在列表或元组中,然后函数返回该列表或元组。2...
    99+
    2023-05-22
    Python
  • python基础之函数的返回值
    函数的返回值 返回结果要怎么做,多个结果又要怎么做 # 函数返回值 # 概念:函数执行完以后会返回一个对象,如果在函数内部有return 就可以返回实际值, # 否则将会返...
    99+
    2024-04-02
  • Linux Shell函数返回值
    Shell函数返回值,一般有3种方式:return,argv,echo 1) return 语句 shell函数的返回值,可以和其他语言的返回值一样,通过return语句返回。 示例: #!/bin/b...
    99+
    2022-06-04
    函数 返回值 Linux
  • golang函数的返回值
    go 语言函数可以使用 return 语句返回多个值,通过调用函数后指定变量接收。返回值数量及类型需在函数声明中明确指定,且函数可返回任意数量的值(但不能返回空值)。 Go 语言函数的...
    99+
    2024-04-19
    返回值 golang
  • javascript如何实现函数返回值
    小编给大家分享一下javascript如何实现函数返回值,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧! 在javascript中,实现函数返回值的语句是retu...
    99+
    2024-04-02
  • PHP函数的返回值类型和返回值说明
    PHP是一种类型松散的编程语言,这意味着它允许开发人员在运行时更轻松地修改变量类型。但是,在编写函数时,开发人员必须清楚函数的返回类型和返回值说明,以确保函数将返回正确的数据类型和结构。PHP函数的返回值类型在5.0版本之前,PHP函数无法...
    99+
    2023-05-18
    PHP函数 返回值类型 返回值说明
  • python怎么让函数没有返回值
    python中通过在函数中添加一个return语句,实现函数没有返回值,具体方法如下:例:定义一个func函数def func(x,y):num = x + yprint(func(1,2))输出结果为:3在函数中添加一个return语句d...
    99+
    2024-04-02
  • python中函数如何返回多个值
    这篇文章给大家介绍python中函数如何返回多个值,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Python的优点有哪些1、简单易用,与C/C++、Java、C# 等传统语言相比,Python对代码格式的要求没有那么严...
    99+
    2023-06-14
  • python函数返回多个值的方法
    这篇文章主要介绍“python函数返回多个值的方法”,在日常操作中,相信很多人在python函数返回多个值的方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python函数返回多个值的方法”的疑惑有所帮助!...
    99+
    2023-06-20
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作