一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術(shù)及教程分享平臺(tái)!
分類導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Python - Python 注解方式實(shí)現(xiàn)緩存數(shù)據(jù)詳解

Python 注解方式實(shí)現(xiàn)緩存數(shù)據(jù)詳解

2022-02-11 23:06liuxing93619 Python

這篇文章主要介紹了Python 注解方式實(shí)現(xiàn)緩存數(shù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

背景

每次加載數(shù)據(jù)都要重新Load,想通過加入的注解方式開發(fā)緩存機(jī)制,每次緩存不用寫代碼了

缺點(diǎn):目前僅支持一個(gè)返回值,雖然能弄成字典,但是已經(jīng)滿足個(gè)人需求,沒動(dòng)力改(狗頭)。

拿來即用

新建文件 Cache.py

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Cache:
    def __init__(self, cache_path='.', nocache=False):
        self.cache_path = cache_path
        self.cache = not nocache
    def __call__(self, func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            s = f'{func.__code__.co_filename}.{func.__name__}'
            s += ','.join(list(args[1:]) + [f'{k}={v}' for k, v in kwargs.items()])
            md5 = hashlib.md5()
            md5.update(s.encode('utf-8'))
            cache_file = f'{self.cache_path}/{md5.hexdigest()}'
            if self.cache and os.path.exists(cache_file):
                print('Loading from cache')
                return pickle.load(open(cache_file, 'rb'))
            else:
                if not os.path.exists(self.cache_path):
                    os.makedirs(self.cache_path)
                data = func(*args, **kwargs)
                pickle.dump(data, file=open(cache_file, 'wb'))
                print(f'Dump finished {cache_file}')
            return data
        return wrapper
?
1
2
3
4
from .Cache import Cache
@Cache(root_path, nocache=True)
def load_data(self, inpath):
    return 'Wula~a~a~!'

實(shí)踐過程

第一次,來個(gè)簡單的繼承父類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Cache(object):
    def __init__(self, cache_path=None):
        self.cache_path = cache_path if cache_path else '.'
        self.cache_path = f'{self.cache_path}/cache'
        self.data = self.load_cache()
    def load_cache(self):
        if os.path.exists(self.cache_path):
            print('Loading from cache')
            return pickle.load(open(self.cache_path, 'rb'))
        else:
            return None
    def save_cache(self):
        pickle.dump(self.data, file=open(self.cache_path, 'wb'))
        print(f'Dump finished {self.cache_path}')
class Filter4Analyzer(Cache):
    def __init__(self, rootpath, datapath):
        super().__init__(rootpath)
        self.root_path = rootpath
        if self.data is None:
            self.data = self.load_data(datapath)
            self.save_cache()

只要繼承Cache類就可以啦,但是有很多局限,例如只能指定某個(gè)參數(shù)被cache,例如還得在Filter4Analyzer里面寫保存的代碼。

下一步,python嵌套裝飾器來改善這個(gè)問題

?
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
from functools import wraps
import hashlib
def cached(cache_path):
    def wrapperper(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            s = f'{func.__code__.co_filename}.{func.__name__}' + ','.join(args[1:])
            s += ','.join(list(args[1:]) + [f'{k}={v}' for k, v in kwargs.items()])
            md5 = hashlib.md5()
            md5.update(s.encode('utf-8'))
            cache_file = f'{cache_path}/{md5.hexdigest()}' if cache_path else './cache'
            if os.path.exists(cache_file):
                print('Loading from cache')
                return pickle.load(open(cache_file, 'rb'))
            else:
                if not os.path.exists(cache_path):
                    os.makedirs(cache_path)
                data = func(*args, **kwargs)
                pickle.dump(data, file=open(cache_file, 'wb'))
                print(f'Dump finished {cache_file}')
            return data
        return wrapper
    return wrapperper
class Tester:
    @cached(cache_path='./workpath_test')
    def test(self, data_path):
        return ['hiahia']

通過裝飾器類簡化代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Cache:
    def __init__(self, cache_path='.', nocache=False):
        self.cache_path = cache_path
        self.cache = not nocache
    def __call__(self, func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            s = f'{func.__code__.co_filename}.{func.__name__}'
            s += ','.join(list(args[1:]) + [f'{k}={v}' for k, v in kwargs.items()])
            md5 = hashlib.md5()
            md5.update(s.encode('utf-8'))
            cache_file = f'{self.cache_path}/{md5.hexdigest()}'
            if self.cache and os.path.exists(cache_file):
                print('Loading from cache')
                return pickle.load(open(cache_file, 'rb'))
            else:
                if not os.path.exists(self.cache_path):
                    os.makedirs(self.cache_path)
                data = func(*args, **kwargs)
                pickle.dump(data, file=open(cache_file, 'wb'))
                print(f'Dump finished {cache_file}')
            return data
        return wrapper

參考:

Python 函數(shù)裝飾器

Python函數(shù)屬性和PyCodeObject

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注服務(wù)器之家的更多內(nèi)容!

原文鏈接:https://blog.csdn.net/liuxing93619/article/details/120837018

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 大胸纲手被羞羞漫画网站 | 精品国产乱码久久久久久软件 | 初尝黑人巨大h文 | 小妇人电影免费完整观看2021 | 天作谜案免费完整版在线观看 | 果冻传媒天美传媒在线小视频播放 | 天天做天天爱天天综合网 | 美妇在男人胯下哀求 | 日产乱码卡一卡2卡三卡四福利 | 95视频在线观看在线分类h片 | 色小妹在线 | 亚洲国产综合久久精品 | 韩国漂亮美女三级在线观看 | 调教催眠| 亚洲国产99999在线精品一区 | 国产精品永久免费视频 | 免费人成在线观看69式小视频 | free性泰国娇小videos | 午夜桃色剧场 | 日韩精品免费一级视频 | 国产一区二区三区久久小说 | 日韩v | 国产欧美成人不卡视频 | 欧美洲大黑香蕉在线视频 | 97se亚洲国产综合自在线观看 | 逼水真多| 亚洲福利精品电影在线观看 | 幸福草电视剧演员表介绍 | 亚洲国产高清一区二区三区 | 日韩毛片免费在线观看 | 91最新国产| 我被黑人彻底征服的全文 | 给我免费的视频在线观看 | 性xxx欧美| 国内精品一区视频在线播放 | 四虎影视网站 | 黄情视频| 日韩欧美一区二区不卡 | 俄罗斯一级在线播放 | 精品牛牛影视久久精品 | 国产白虎|