序列化:json,pickle,itsdangerous中的loads\dumps的对比分析

序列化

        将原本的字典、列表等格式的内容转换成一个字符串的过程。程序间的数据传递需要一定的规范格式,序列化,反序列化做的就是这件事。

将字典转换成一个字符串很简单,str(dic) 就可以办到,为什么还要又序列化模块呢?

        的确,str(dic) 就可以完成字典到字符串的转换,但是怎样才能把字符串转换为字典还没解决,eval() 可以,将一个字符串类型的字典str_dic给eval,就可以得到一个返回的字典类型。这看似很好,其实有着安全隐患,eval的功能是将字符串str当作有效的表达式来求值并返回计算结果。试想如果从文件中读出的不是一个简单的数据结构,而是一句类似删除文件的破坏性语句,那么后果gg....所以,不推荐eval方法进行反序列化操作(str --> python中的数据类型)

Python中 json、pickle以及itsdangerous 都具备序列化功能,下面我们一一来看:

 

一、json中的json.dumps和json.loads:

  • 序列化:json.dumps() 将一个Python数据类型进行json格式的编码解析(dict转成str)
  • 反序列化:json.loads() 将json格式的基于字典的字符串转换成Python数据类型(str转成dict)
import json
data_dict = {"name": "xxx", "gender": "female"}
# <class 'dict'>
print(type(data_dict))
data_str = json.dumps(data_dict)
# <class 'str'>
print(type(data_str))
data_dict_1 = json.loads(data_str)
# <class 'dict'>
print(type(data_dict_1))

    扩展

     json.loads和json.load,json.dumps和json.dump的区别

     json.dump是将python数据保存成json。主要配合json.load来使用。

  • json.dump(x,f),x是对象,f是文件对象,将json数据写入到f文本文件当中。
  • json.load是读取json数据 。主要配合json.dump来使用。
import json
data_dict = {"name": "xxx", "gender": "female"}
f = open('xxx.txt', 'w')
json.dump(data_dict, f)
# 这样就生成了一个xxx.txt文件,保存了json格式的数据
# json.load加载json格式文件
f = open('xxx.txt', 'r')
data = json.load(f)
# 输出读取的数据
print(data)    

 

 

二、pickle中的pickle.dumps和pickle.loads:

  • pickle.dumps():  将obj对象序列化并返回一个bytes对象(某一个数据类型转成bytes)
  • pickle.loads():  将bytes反序列化并返回一个对象(bytes转成之前的数据类型)
import pickle
data_dict = {"name": "xxx", "gender": "female"}
data_dumps = pickle.dumps(data_dict)
# <class 'bytes'>
print(type(data_dumps))
data_loads = pickle.loads(data_dumps)
# <class 'dict'>
print(type(data_loads))

扩展:

pickle.loads和pickle.load,pickle.dumps和pickle.dump的区别

  • pickle.dump()方法将obj对象序列化为字节(bytes)写入到file文件中
  • pickle.load()从一个对象文件中读取序列化数据,将其反序列化之后返回一个对象
f = open('xxx.txt', 'wb')
pickle.dump(data_dict, f)
data = pickle.load('xxx.txt')
f.close()

 

 

三、itsdangerous中的itsdangerous.dumps和itsdangerous.loads:

序列化
因为字符串难以处理,本模块也提供了一个与json或pickle类似的序列化接口。(它内部默认使用simplejson,但是可以通过子类进行修改)
:class:`Serializer`类实现了:
>>> from itsdangerous import Serializer
>>> s = Serializer('secret-key')
>>> s.dumps([1, 2, 3, 4])
'[1, 2, 3, 4].r7R9RhGgDPvvWl3iNzLuIIfELmo'
它当然也可以加载数据:

>>> s.loads('[1, 2, 3, 4].r7R9RhGgDPvvWl3iNzLuIIfELmo')
[1, 2, 3, 4]

 

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
    @staticmethod
    def generate_save_user_token(openid):
        # """
        # 生成保存用户数据的token
        # :param openid: 用户的openid
        # :return: token
        # """
        serializer = Serializer(settings.SECRET_KEY, expires_in=contents.SAVE_QQ_USER_TOKEN_EXPIRES)
        data = {'openid': openid}
        token = serializer.dumps(data)
        return token.decode()

    @staticmethod
    def check_save_user_token(token):
        # """
        # 检验保存用户数据的token
        # :param token: token
        # :return: openid or None
        # """
        serializer = Serializer(settings.SECRET_KEY, expires_in=contents.SAVE_QQ_USER_TOKEN_EXPIRES)
        try:
            data = serializer.loads(token)
        except BadData:
            return None
        else:
            return data.get('openid')

 

 

json-pickle-itsdangerous对比总结:

1-pickle不是用于多种语言间的数据传输,它仅作为python对象的持久化,只针对python的数据类型;而json可以支持更多语言的序列化和反序列化,在python中序列化一个自定义的类对象时,会抛出一个 TypeError; 
2-json的序列化输出是文本对象是str类型,而pickle序列化的输出是二进制字节-bytes

3-json可读性优于pickle。

4-itsdangerous也提供了一个与json或pickle类似的序列化接口。(它内部默认使用simplejson,但是可以通过子类进行修改)

5-pickle:就是将python数据转成原始的二进制数据;

    itsdangerous:就是通过密钥secret-key进行加密处理。多用于生成token。

6-jsonify和json.dumps()

jsonify的作用实际上就是将我们传入的json形式数据序列化成为json字符串,作为响应的body,并且设置响应的Content-Type为application/json,构造出响应返回至客户端。jsonify的部分源码如下:

def jsonify(*args, **kwargs):
    indent = None
    if current_app.config['JSONIFY_PRETTYPRINT_REGULAR'] \
        and not request.is_xhr:
        indent = 2
    return current_app.response_class(dumps(dict(*args, **kwargs),
        indent=indent),
        mimetype='application/json')

jsonify将dict类型转变为json对象。json.dumps只是将dict类型转化为str类型,并非一个json对象。

jsonify其实也是用dumps方法转换成了json格式的字符串,但是jsonify会根据http协议的body进行格式重新编排。而json.dumps只是单纯的将dict类型转化为str类型,可以直接return json.dumps(data)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值