zoukankan      html  css  js  c++  java
  • python基础之模块 序列化

    什么是序列化(picking)?

     我们把变量从内存中变成可存储或传输的过程称之为序列化。

     序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。

     反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

    ---如何序列化?

      在python中提供了两个模块可进行序列化。分别是pickle和json。

    pickle

      pickle是python中独有的序列化模块,所谓独有,就是指不能和其他编程语言的序列化进行交互,因为pickle将数据对象转化为bytes

    >>> import pickle
    >>> d=[1,2,3,4]
    >>> pickle.dumps(d)
    b'x80x03]qx00(Kx01Kx02Kx03Kx04e.'
    >>> type(pickle.dumps(d))
    <class 'bytes'>     #类型为bytes
    

    pickle模块提供了四个功能:dumps、dump、loads、load。

      dumps和dump都是进行序列化,而loads和load则是反序列化。

    >>> import pickle
    >>> d=[1,2,3,4]
    >>> pickle.dumps(d)
    b'x80x03]qx00(Kx01Kx02Kx03Kx04e.'
    

     dumps将所传入的变量的值序列化为一个bytes,然后,就可以将这个bytes写入磁盘或者进行传输。

      而dump则更加一步到位,在dump中可以传入两个参数,一个为需要序列化的变量,另一个为需要写入的文件。

    f=open('file_test','wb')
    >>> d=[1,2,3,4]
    >>> pickle.dump(d,f)
    >>> f.close()
    >>> f=opem('file_test','rb')
     f=open('file_test','rb')
    >>> f.read()
    b'x80x03]qx00(Kx01Kx02Kx03Kx04e.'
    

    loads当我们要把对象从磁盘读到内存时,可以先把内容读到一个bytes,然后用loads方法反序列化出对象,也可以直接用load方法直接反序列化一个文件。

    >>> d=[1,2,3,4]
    >>> r=pickle.dumps(d)
    >>> print(r)
    b'x80x03]qx00(Kx01Kx02Kx03Kx04e.'
    >>> pickle.loads(r)
    [1, 2, 3, 4]

    #####load####

    >>> d=[1,2,3,4]
    >>> f=open('file_test','wb')
    >>> pickle.dump(d,f)
    >>> f.close()
    >>> f=open('file_test','rb')
    >>> r=pickle.load(f)
    >>> f.close()
    >>> print(r)
    [1, 2, 3, 4]

    json

      如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。

      如果想要详细了解JSON的话,推荐一篇博文:http://www.cnblogs.com/mcgrady/archive/2013/06/08/3127781.html

      json中的方法和pickle中差不多,也是dumps,dump,loads,load。使用上也没有什么区别,区别在于,json中的序列化后格式为字符。

    >>> import json
    >>> d=[1,2,3,4]
    >>> json.dumps(d)
    '[1, 2, 3, 4]'
    >>> type(json.dumps(d))
    <class 'str'>           #类型为str
    

    因为python中一切事物皆对象,所有对象都是基于类创建的,所以,‘类’在python中占据了相当大的比重。我们能否将类的实例进行序列化呢?

    >>> class student(object):
    ...     def __init__(self,name,age,course):
    ...         self.name=name
    ...         self.age=age
    ...         self.course=course
    ...         
    >>> a=student('linghuchong',24,'xixingdafa')
    >>> import json
    >>> json.dumps(a)
    TypeError: <student object at 0x035B8230> is not JSON serializable
    

    晕,竟然不能!现在几乎都是面向对象编程,类这么重要,竟然不能序列化,怎么搞?

    不要着急,前面的代码之所以无法把student类实例序列化为JSON,是因为默认情况下,dumps方法不知道如何将student实例变为一个JSON的'{}'对象。

    我们需要’告诉‘json模块如何转换。

    >>> def st_to_dict(a):
    ...     return {'name':a.name,'age':a.age,'course':a.course}
    ...     
    >>> print(json.dumps(a,default=st_to_dict))          #default参数就是告知json如何进行序列化
    {"course": "xixingdafa", "name": "linghuchong", "age": 24}
    

    当然,如果我们每定义一个类,还得再定义一下这个类的实例转换为字典的函数实在是太麻烦了!!我们有一个一劳永逸的办法。

    print(json.dumps(a, default=lambda obj: obj.__dict__))
    

    其中的__dict__不需我们在类中定义,因为通常class的实例都有一个__dict__属性,它就是一个字典,用来存储实例变量。

    >>> print(a.__dict__)
    {'course': 'xixingdafa', 'age': 24, 'name': 'linghuchong'}
    

     

  • 相关阅读:
    ajax 传递参数中文乱码解决办法
    jQuery 时间戳转化成时间
    IDEA2017 导入 SVN上的 Myeclipse或Eclipse 项目
    ajax返回json数据,对其中日期的解析
    MYSQL 按照字母排序查询
    JVM介绍
    正则表达式
    could not find the main class错误
    转:MyEclipse使用总结——MyEclipse10安装SVN插件
    转:Oracle数据库sqlplus与plsqldev解决乱码
  • 原文地址:https://www.cnblogs.com/nulige/p/6579577.html
Copyright © 2011-2022 走看看