Python序列化和延迟读文件

好久没写文章了,最近在工作中恰好要用到python一些特性,随便记录一些片段代码:

Python序列化

序列化的方式有很多,大体可分为可自描述和非自描述。比如Json,只要有一个Json文件就可以推断数据格式,那就是自描述的,protobuf需要额外的描述文件.proto才能正确解析,就是非自描述。python的序列化库调研了一下,最后觉得还是自带的pickle最方便,不过也是非自描述的类型,需要事先准备好python的数据结构。

延迟读文件

延迟读文件的需求来源于项目建模时需要读很多外部数据和配置文件,但是真正执行的模型的时候,有些配置和数据可能是不需要的,但是又不想在运行模型前再读配置文件,这样就不统一了,所以想到了延迟加载文件的方式。Python语言特性恰好支持闭包和高阶函数,正好用这个方式实现延迟读文件。

代码举例

其它的就不多说,核心代码片段记录一下,实际用于工程中还得完善一下:

import gzip

import json

import pickle

# import _pickle as pickle # 原生C实现cpickle

import time



import numpy



# 耗时统计(装饰器)

def time_cost(f):

    def inner(*arg, **kwarg):

        s_time = time.time()

        res = f(*arg, **kwarg)

        e_time = time.time()

        print('cost:{} s'.format(e_time - s_time))

        return res



    return inner





# pickle序列化

@time_cost

def serialize(filename, obj, compress=False):

    if compress:

        with gzip.open(filename, 'wb') as fp:

            pickle.dump(obj, fp)

    else:

        with open(filename, 'wb') as fp:

            pickle.dump(obj, fp)





# pickle反序列化

@time_cost

def deserialize(filename, compress=False):

    if compress:

        with gzip.open(filename, 'rb') as fp:

            return pickle.load(fp)

    else:

        with open(filename, 'rb') as fp:

            return pickle.load(fp)





# 延迟加载文件

def load_config(filename):

    def open_json():

        with open(filename) as fp:

            print("open json:", filename)

            return json.load(fp)



    return open_json





if __name__ == "__main__":

    arr1 = numpy.random.randint(1000, size=[1920, 1080])

    arr2 = numpy.random.randint(1000, size=[1280, 720])

    arr3 = numpy.random.randint(1000, size=[1024, 768])

    arr4 = numpy.random.randint(1000, size=[2560, 1440])

    dict1 = {"arr1": arr1, "arr2": arr2, "arr3": arr3, "arr4": arr4}

    print(arr1[0][1])

    serialize('dict1.dat', dict1, False)

    dict2 = deserialize('dict1.dat', False)

    print(dict2["arr1"][0][1])



    json_data = load_config('json-data.json')

    print('lazy load')

    json = json_data()

    print(json['address']['streetAddress'])