zoukankan      html  css  js  c++  java
  • python 序列化、JSON

    在程序运行的过程中,所有的变量都是在内存中,比如,定义一个dict:
    d = dict(name='Bob', age=20, score=88)

    可以随时修改变量,比如把name改成'Bill',但是一旦程序结束,变量所占用的内存就被操作系统全部回收。如果没有把修改后的'Bill'存储到磁盘上,下次重新运行程序,变量又被初始化为'Bob'。
    我们把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。
    序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。
    反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

    关于Django中的序列化主要应用在将数据库中检索的数据返回给客户端用户,特别的Ajax请求一般返回的为Json格式

    view视图中序列化如下:

     1、serializers

    from django.core import serializers
    ret = models.BookType.objects.all()
    data = serializers.serialize("json", ret)
    

    2、json.dumps

    import json
    #ret = models.BookType.objects.all().values('caption')
    ret = models.BookType.objects.all().values_list('caption')
    ret=list(ret)
    result = json.dumps(ret)
    

     由于json.dumps时无法处理datetime日期,所以可以通过自定义处理器来做扩展,如:

    import json 
    from datetime import date 
    from datetime import datetime 
       
    class JsonCustomEncoder(json.JSONEncoder): 
        
        def default(self, field): 
         
            if isinstance(field, datetime): 
                return o.strftime('%Y-%m-%d %H:%M:%S') 
            elif isinstance(field, date): 
                return o.strftime('%Y-%m-%d') 
            else: 
                return json.JSONEncoder.default(self, field) 
       
       
    # ds = json.dumps(d, cls=JsonCustomEncoder)
    

     html前端页面序列化及反序列化:

     function myajax(){  // 创建点击事件函数
                var temp = $('#ajax_id').val(); //获取input标签id=ajax_id的值,用户输入
                var user_list = [
                {'username':'yangmv','age':18},
                {'username':'wj','age':28}];
    
                $.ajax({
                    url:'/ajax_app/test',
                    type:'POST',
                    tradition:true,  {#对数据原生处理,不做加工#}
                    data:{data0:temp,data1:JSON.stringify(user_list),csrfmiddlewaretoken:'{{ csrf_token  }}'}, {#类似以json.dumps转换为字符串的方式传输#}
                    success:function (arg) {   //如果程序执行,arg为返回的数据
                        var obj = jQuery.parseJSON(arg); {#把返回的字符串数据类似用json.load解码为对象#}
                        if(obj.status){   //status字段为view中定义好的字段,为True
                            alert('okkkkk');
                        }else{
                            alert('obj.msg');
                    }
                    }
                });
    
            }
    

    Pickle模块

    Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系

    >>> import pickle 
    >>> d = dict(name='Bob', age=20, score=88) 
    >>> pickle.dumps(d) 
    b'x80x03}qx00(Xx03x00x00x00ageqx01Kx14Xx05x00x00x00scoreqx02KXXx04x00x00x00nameqx03Xx03x00x00x00Bobqx04u.'

     pickle.dumps()方法把任意对象序列化成一个bytes,然后,就可以把这个bytes写入文件。
    或者用另一个方法pickle.dump()直接把对象序列化后写入一个file-like Object:

    >>> f = open('dump.txt', 'wb')
    >>> pickle.dump(d, f)
    >>> f.close()
    

     对象从磁盘读到内存时,可以先把内容读到一个bytes,然后用pickle.loads()方法反序列化出对象,
    也可以直接用pickle.load()方法从一个file-like Object中直接反序列化出对象

    >>> f = open('dump.txt', 'rb')
    >>> d = pickle.load(f)
    >>> f.close()
    >>> d
    {'age': 20, 'score': 88, 'name': 'Bob'}
    

    JSON

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

    语法:

    json.dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding="utf-8", default=None, sort_keys=False, **kw)
    json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])
    

     存储到json文件中:

    dic = {'age': 23, 'job': 'student'}
    with open('abc.json', 'w', encoding='utf-8') as f:
        json.dump(dic, f)
    
    with open('abc.json', encoding='utf-8') as f:
        obj = json.load(f)
        print(obj)
    

    json进阶

    class Student(object):
        def __init__(self,name,age,score):
            self.name = name
            self.age =age
            self.score=score
    s=Student('Bob',20,95)
    # 默认情况下,dumps()方法不知道如何将Student实例变为一个JSON的{}对象。
    #可选参数default就是把任意一个对象变成一个可序列为JSON的对象,我们只需要
    #为Student专门写一个转换函数,再把函数传进去即可
    def student2dict(std):
        return {
            'name':std.name,    
            'age':std.age,
            'score':std.score
        }
    
    #Student实例首先被student2dict()函数转换成dict,
    #然后再被顺利序列化为JSON
    print(json.dumps(s,default =student2dict))
    
    #通常class的实例都有一个__dict__属性,它就是一个dict,
    #用来存储实例变量。也有少数例外,比如定义了__slots__的class
    print(json.dumps(s,default =lambda obj:obj.__dict__))
    
    #把JSON反序列化为一个Student对象实例,loads()方法首先转换出一个dict对象,
    #然后,我们传入的object_hook函数负责把dict转换为Student实例
    def dict2student(d):
        return Student(d['name'],d['age'],d['score'])
    	
    json_str ='{"age":20,"score":98,"name":"Bob"}'
    #打印出的是反序列化的Student实例对象
    print(json.loads(json_str,object_hook=dict2student))
    

    decode、encode函数:

    import demjson
    data = [ { 'a' : 1, 'b' : 2, 'c' : 3, 'd' : 4, 'e' : 5 } ]
    json = demjson.encode(data)
    print json
    
    json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
    
    text = demjson.decode(json)
    print  text
    
  • 相关阅读:
    el-select下拉框选项太多导致卡顿,使用下拉框分页来解决
    vue+elementui前端添加数字千位分割
    Failed to check/redeclare auto-delete queue(s)
    周末啦,做几道面试题放松放松吧!
    idea快捷键
    解决flink运行过程中报错Could not allocate enough slots within timeout of 300000 ms to run the job. Please make sure that the cluster has enough resources.
    用.net平台实现websocket server
    MQTT实战3
    Oracle 查看当前用户下库里所有的表、存储过程、触发器、视图
    idea从svn拉取项目不识别svn
  • 原文地址:https://www.cnblogs.com/honey-badger/p/8942039.html
Copyright © 2011-2022 走看看