python文件处理结果缓存装饰器

0.起因

在python处理的各类杂活中,文件格式转换类工作通常占大多数比例,比如:
+ 小王啊, 这个.txt帮忙转成xls格式
+ 小张啊, 把这个xls里面xx数据提取出来,搞个xml文件
+ 小周啊, 解析下这个xml文件,转成.txt给我.

通常这种的代码结构可以分成两块:
1. 原始文件解析, 保存为内部数据
2. 将内部数据转换成要求的新文件格式
这篇文件主要是优化第一步. 因为接到一个杂活,要处理大概1000多个xls文件, 而且文件大小比较对不起硬盘,转换逻辑有点绕, 第一步的解析过程可能要花10分钟左右, 并且只要一个文件更新后,就要重新生成.OK, 问题就是这样了.

1.经过

为了解决这个问题,我决定保存第一步的内部数据, 对于这种功能,pickle就是你想要的了. 为了通用性和易用性,决定做个装饰器.所以代码如下:

import os
from functools import wraps

try:
    import cPickle as pickle
except ImportError:
    import pickle

def file_cache(parse_func):

    def _check_cache_valid(parse_file, cache_file):
        if not os.path.isfile(cache_file):
            return False

        if os.path.getmtime(parse_file) > os.path.getmtime(cache_file):
            return False

        return True

    @wraps(parse_func)
    def _wrap(*args, **kwargs):
        parse_file = kwargs.get('parse_file', '')
        parse_result = None
        cache_file = '.'.join([parse_file, 'cache'])
        if _check_cache_valid(parse_file, cache_file):
            with open(cache_file) as cache_fd:
                parse_result = pickle.load(cache_fd)
        else:
            parse_result = parse_func(*args, **kwargs)
            with open(cache_file, 'w') as cache_fd:
                pickle.dump(parse_result, cache_fd)

        return parse_result

    return _wrap

几点说明:

  1. 要解析的文件名,必须通过parse_file参数指明
  2. 每个文件的缓存文件为文件名加.cahce
  3. 通过判断原文件和缓冲文件的修改时间来确定,是否要更新缓存文件

应用场景

  @file_cache
   def _parse_translate_info(self, parse_file=None):
        translate_info = {}
        with open(parse_file) as fin:
            for line in fin:
                match = self.TRANSLATE_LINE.match(line)
                if match:
                    translate_info[match.group('en')] = match.group('cn').decode('utf8')

        return translate_info

对于老的一些脚本, 要想支持这功能, 少量改动代码就可以了.装饰器大法好啊.

2.结果

引入缓存后,解析速度就是 咻咻咻. (缓存是计算机科学里最NB的发明)

3.警告

以上代码只是处理简单任务的版本,缺少各类异常情况的处理,使用时出现问题概不负责的说。

你可能感兴趣的:(python文件处理结果缓存装饰器)