zoukankan      html  css  js  c++  java
  • Python中的json操作

    Python中的json操作

    标签(空格分隔): python 编码 json


    字符串前缀问题

    字符串前缀可以有r,u
    r:表示原始(raw)字符串,比如' '不会被转义。常用于正则。

    u:表示unicode字符串。
    python3系列的字符串默认是unicode,无需用u进行转码。我用的是python2.7,所以还是要手动处理编码。

    发生问题的一个场景是:从某个url抓取json格式数据,import了python自带的jsonsimplejson包,调用其loads()方法后,得到的对象(字典)的key的类型是unicode,形如:

    obj={
        u'name':'chris',
        u'age':22
    }
    

    而我当前的一个函数,传入参数为一个dict字典,用它生成为sql语句,带着u的insert语句插入数据库会报错。需要去除u

    u是unicode类型,不带u的是字符串类型。对于一个unicode变量,可以用encode()函数转为str类型。但是现在有一整个字典的key都要转换,我不知道怎么转换。

    一个解决方法是重写一个json构建/解析的函数。我并不想重复造轮子,只是python2.7下json和simplejson两个包太难用。尝试了各种参数,还是无法得到key为str类型而不是unicode类型的结果。

    我传给你的是ascii编码的对象,为什么不能返还给我一个ascii编码的对象?果断自己写一个好用的。

    一个简陋的json构建/解析实现

              dumps(序列化)
         -------------------> 
     obj                        str
     对象                       字符串
         <-------------------
             loads(反序列化)
        
    
    

    这里采用类似dumps和loads的名字,不过加了自己的前缀。
    从obj对象(python中是字典类型)到str类型,是序列化(dumps)的过程;把str解析后装载为obj对象,是反序列化(loads)的过程。序列化目的在于网络传输。

    #!/usr/bin/python
    #coding:utf-8
    
    import types
    
    #从obj到str
    def chris_dumps(dict_data):
        jar=""
        result = chris_dumps_iter(dict_data, jar)
        return "{"+result+"}"
    
    def chris_dumps_iter(dict_data, jar):
        for k in dict_data:
            jar = jar + """ + k + "": "
            if isinstance(dict_data[k], dict):
                tmp = chris_dumps(dict_data[k])
                jar = jar+tmp
            elif isinstance(dict_data[k], basestring):
                jar = jar + """+dict_data[k]+"""
            else:
                jar = jar + str(dict_data[k])
            jar = jar + ", "
        return jar[0:len(jar)-2]
    
    #从str到objs
    def chris_loads(data):
        jar = {}
        result = chris_loads_iter(data, jar)
        return result
    
    def chris_loads_iter(data, jar):
        cnt = 0  # count brackets  {:+1   }:-1
        key = ""
        val = ""
        quote=False
        colon = False   # 冒号,False表示在冒号左边,True表示在右边
        #for i in xrange(len(data)):
        i=0
        while i<len(data):
            if quote:            
                if data[i]==""": #右引号
                    if colon==False: 
                        quote=False
                    else:
                        val += data[i]
                else:
                    key += data[i]
                    
            else:
                if data[i]==""": #左引号
                    if colon==False:
                        quote=True
                        key = ""
                    else:
                        val += data[i]
                elif data[i]==":":
                    colon = True
                elif data[i]=="," or data[i]=='}':
                    #jar[key]=eval(val) #干的漂亮!
                    jar[key]=eval(val)
                    val = ""
                    colon = False
                elif data[i]==" ":
                    pass
                elif data[i]=="{":
                    if colon==True :
                        j=i
                        subdata = ""
                        while data[j]!='}':
                            subdata += data[j]
                            j += 1
                        subdata += "}"
                        i=j+1
                        sub_result = chris_loads(subdata)
                        val=sub_result
                        jar[key]=sub_result
                        val = ""
                        colon = False
                else:
                    val += data[i]
            i += 1 
        return jar
    

    写好了,测试一下:

    if __name__ == "__main__":
        s1={'name':'chris', 'age': 22}
        s={'name':'chris', 'age':22, 'property': { 'id': 2011, 'lang': 'chinese'}}
        t=chris_dumps(s)
        g=s['property']
         
        print 't:', t
        q=chris_loads(t)
        print 'q:', q
        print type(q)
    

    P.S.其实这个loads函数写的并不优美,正确的思路应当是画出状态自动机,列出每种情况以及各个情况之间的转化关系。

    Greatness is never a given, it must be earned.
  • 相关阅读:
    Educational Codeforces Round 28 B. Math Show
    Educational Codeforces Round 28 A. Curriculum Vitae
    Codeforces Round #433 (Div. 2, based on Olympiad of Metropolises) D. Jury Meeting
    Codeforces Round #433 (Div. 2, based on Olympiad of Metropolises) C. Planning
    2017 Multi-University Training Contest 2 hdu 6047
    2017 Multi-University Training Contest 2 hdu 6045
    2017 Multi-University Training Contest 1 hdu 6043
    2017 Multi-University Training Contest 1 hdu 6034
    2017 Multi-University Training Contest 1 hdu 6033
    poj 2104主席树求区间第k小
  • 原文地址:https://www.cnblogs.com/zjutzz/p/4584704.html
Copyright © 2011-2022 走看看