楼主: 北方Smile
1366 2

[CDA数据分析师学习之路] Python开发:缓存机制介绍 [推广有奖]

  • 0关注
  • 3粉丝

硕士生

15%

还不是VIP/贵宾

-

威望
0
论坛币
15 个
通用积分
0
学术水平
1 点
热心指数
1 点
信用等级
1 点
经验
883 点
帖子
84
精华
0
在线时间
16 小时
注册时间
2016-3-28
最后登录
2016-4-8

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

核子可乐译 51CTO


【51CTO快译】在今天的文章中,我们将一同从简单示例出发,了解如何使用缓存机制。在此之后,我们将进一步利用Python标准库的functools模块创建适合自己需要的缓存。闲言少叙,马上开始。

缓存是一种将定量数据加以保存以备迎合后续请求的处理方式,旨在加快数据的检索速度。在今天的文章中,我们将一同从简单示例出发,了解如何使用缓存机制。在此之后,我们将进一步利用Python标准库的functools模块创建适合自己需要的缓存。作为起步工作,我们首先创建一个类,用于构建我们的缓存字典,而后根据需要进行扩展。以下为具体代码:


  • 1


    [color=rgb(49, 124, 197) !important]2


    3


    [color=rgb(49, 124, 197) !important]4


    5


    [color=rgb(49, 124, 197) !important]6


    7


    [color=rgb(49, 124, 197) !important]8



    [color=rgb(255, 128, 0) !important]########################################################################
    [color=rgb(128, 0, 128) !important]class [color=rgb(0, 45, 122) !important]MyCache[color=rgb(0, 111, 224) !important]:
        [color=rgb(0, 128, 0) !important]""""""
        [color=rgb(255, 128, 0) !important]#----------------------------------------------------------------------
        [color=rgb(128, 0, 128) !important]def [color=rgb(0, 78, 208) !important]__init__[color=rgb(51, 51, 51) !important]([color=rgb(128, 0, 128) !important]self[color=rgb(51, 51, 51) !important])[color=rgb(0, 111, 224) !important]:
            [color=rgb(0, 128, 0) !important]"""Constructor"""
            [color=rgb(128, 0, 128) !important]self[color=rgb(51, 51, 51) !important].cache [color=rgb(0, 111, 224) !important]= [color=rgb(51, 51, 51) !important]{[color=rgb(51, 51, 51) !important]}
            [color=rgb(128, 0, 128) !important]self[color=rgb(51, 51, 51) !important].[color=rgb(0, 45, 122) !important]max_cache[color=rgb(51, 51, 51) !important]_size [color=rgb(0, 111, 224) !important]= [color=rgb(206, 0, 0) !important]10













二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:python IMPORTANT import struct porta 可乐 文章 开发 如何

沙发
北方Smile 发表于 2016-4-6 10:21:32 |只看作者 |坛友微信交流群
在以上类示例中没有包含什么特别之处。我们只是创建一个简单类,同时设置两个类变量或者说属性,即cahce与max_cache_size。其中cache属于一套空字典,而max_cache_size显然代表着最大缓存容量。下面让我们进一步充实该代码,使其具备一定功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import datetime
import random
########################################################################
class MyCache:
    """"""
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        self.cache = {}
        self.max_cache_size = 10
    #----------------------------------------------------------------------
    def __contains__(self, key):
        """
        根据该键是否存在于缓存当中返回True或者False
        """
        return key in self.cache
    #----------------------------------------------------------------------
    def update(self, key, value):
        """
        更新该缓存字典,您可选择性删除最早条目
        """
        if key not in self.cache and len(self.cache) >= self.max_cache_size:
            self.remove_oldest()
        self.cache[key] = {'date_accessed': datetime.datetime.now(),
                           'value': value}
    #----------------------------------------------------------------------
    def remove_oldest(self):
        """
        删除具备最早访问日期的输入数据
        """
        oldest_entry = None
        for key in self.cache:
            if oldest_entry == None:
                oldest_entry = key
            elif self.cache[key]['date_accessed'] < self.cache[oldest_entry][
                'date_accessed']:
                oldest_entry = key
        self.cache.pop(oldest_entry)
    #----------------------------------------------------------------------
    @property
    def size(self):
        """
        返回缓存容量大小
        """
        return len(self.cache)


在这里,我们导入了datetime与random模块,而后我们即可看到之前创建完成的类。这一次,我们向其中添加几种方法。其中一种方法具备神奇的效果,名为_contains_。虽然在这里并不一定要使用该方法,但其基本思路在于允许我们检查该类实例,从而了解其中是否包含有我们正在寻找的键。另外,update方法负责利用新的键/值对进行缓存字典更新。一旦达到或者超出缓存最大容量,其还会删除日期最早的输入数据。另外,remove_oldest方法负责具体的字典内早期数据删除工作。最后,我们还引入了名为size的属性,其能够返回缓存的具体容量。
在添加了以下代码之后,我们就能够测试该缓存是否按预期起效:
if __name__ == ‘__main__’:    #测试缓存    keys = [‘test’, ‘red’, ‘fox’, ‘fence’, ‘junk’,            ‘other’, ‘alpha’, ‘bravo’, ‘cal’, ‘devo’,            ‘ele’]    s = ‘abcdefghijklmnop’    cache = MyCache()    for i, key in enumerate(keys):        if key in cache:            continue        else:            value = ”.join([random.choice(s) for i in range(20)])            cache.update(key, value)        print(“#%s iterations, #%s cached entries” % (i+1, cache.size))    print
在本示例当中,我们设置了大量预定义键与循环。如果键尚不存在,我们会将其添加到缓存当中。不过以上示例代码并没有提到如何更新访问日期,感兴趣的朋友们可以将其作为练习自行探索。在运行这段代码之后,大家会注意到当缓存被占满时,其会正确删除时间更早的条目。
现在,我们继续前进,看看如何利用另一种方式使用Python的内置functools模块创建缓存。

使用道具

藤椅
北方Smile 发表于 2016-4-6 10:22:14 |只看作者 |坛友微信交流群
使用functools.lru_cache
Python的functools模块提供一种非常实用的装饰器,即lru_cache。需要注意的是,其在3.2版本当中才被添加进来。根据说明文档所言,该装饰器能够“利用可调用内存对函数进行打包,从而削减最近调用的最大尺寸。”接下来,我们将根据说明文档中提到的示例编写一项基本功能,其中包含多个网络页面。在这种情况下,我们可以直接从Python说明文档站点处获取页面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import urllib.error
import urllib.request
from functools import lru_cache
@lru_cache(maxsize=24)
def get_webpage(module):
    """
    获取特定Python模块网络页面
    """
    webpage = "https://docs.python.org/3/library/{}.html".format(module)
    try:
        with urllib.request.urlopen(webpage) as request:
            return request.read()
    except urllib.error.HTTPError:
        return None
if __name__ == '__main__':
    modules = ['functools', 'collections', 'os', 'sys']
    for module in modules:
        page = get_webpage(module)
        if page:
            print("{} module page found".format(module))


在以上代码当中,我们利用lru_cache对get_webpage函数进行了装饰,并将其最大尺寸设置为24条调用。在此之后,我们设置了一条网页字符串变量,并将其传递至我们希望函数获取的模块当中。根据我的个人经验,如果大家将其运行在某种Python解释器当中——例如IDLE——那么效果会更好。如此一来,我们就能够针对该函数运行多次循环。可以看到在首次运行上述代码时,输出结果的显示速度相对比较慢。但如果大家在同一会话中再次加以运行,那么其显示速度将极大加快——这意味着lru_cache已经正确对该调用进行了缓存处理。大家可以在自己的解释器实例当中进行试验并亲自查看结果。
另外,我们还可以将一条typed参数传递至该装饰器。其属于一条Boolean,旨在通知该装饰器在typed为设定为True时对不同类型参数进行分别缓存。
总结
现在大家已经初步了解了如何利用Python编写自己的缓存机制。这是一款有趣的工具,而且能够在各位面对大量高强度I/O调用或者希望对登录凭证等常用信息进行缓存时发挥重要作用。
原文标题:Python开发:缓存机制介绍
注:转载文章均来自于公开网络,仅供学习使用,不会用于任何商业用途,如果侵犯到原作者的权益,请您与我们联系删除或者授权事宜,联系邮箱:contact@dataunion.org。转载数盟网站文章请注明原文章作者,否则产生的任何版权纠纷与数盟无关。

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-27 13:32