標(biāo)準(zhǔn)庫(kù)(8)

2018-02-24 15:48 更新

json

就傳遞數(shù)據(jù)而言,xml是一種選擇,還有另外一種,就是json,它是一種輕量級(jí)的數(shù)據(jù)交換格式,如果讀者要做web編程,是會(huì)用到它的。根據(jù)維基百科的相關(guān)內(nèi)容,對(duì)json了解一二:

JSON(JavaScript Object Notation)是一種由道格拉斯·克羅克福特構(gòu)想設(shè)計(jì)、輕量級(jí)的資料交換語(yǔ)言,以文字為基礎(chǔ),且易於讓人閱讀。儘管JSON是Javascript的一個(gè)子集,但JSON是獨(dú)立於語(yǔ)言的文本格式,並且採(cǎi)用了類似於C語(yǔ)言家族的一些習(xí)慣。

關(guān)于json更為詳細(xì)的內(nèi)容,可以參考其官方網(wǎng)站:http://www.json.org

從官方網(wǎng)站上摘取部分,了解一下json的結(jié)構(gòu):

JSON建構(gòu)于兩種結(jié)構(gòu):

  • “名稱/值”對(duì)的集合(A collection of name/value pairs)。不同的語(yǔ)言中,它被理解為對(duì)象(object),紀(jì)錄(record),結(jié)構(gòu)(struct),字典(dictionary),哈希表(hash table),有鍵列表(keyed list),或者關(guān)聯(lián)數(shù)組 (associative array)。
  • 值的有序列表(An ordered list of values)。在大部分語(yǔ)言中,它被理解為數(shù)組(array)。

python標(biāo)準(zhǔn)庫(kù)中有json模塊,主要是執(zhí)行序列化和反序列化功能:

  • 序列化:encoding,把一個(gè)python對(duì)象編碼轉(zhuǎn)化成json字符串
  • 反序列化:decoding,把json格式字符串解碼轉(zhuǎn)換為python數(shù)據(jù)對(duì)象

基本操作

json模塊相對(duì)xml單純了很多:

>>> import json
>>> json.__all__
['dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONEncoder']

encoding: dumps()

>>> data = [{"name":"qiwsir", "lang":("python", "english"), "age":40}]
>>> print data
[{'lang': ('python', 'english'), 'age': 40, 'name': 'qiwsir'}]
>>> data_json = json.dumps(data)
>>> print data_json
[{"lang": ["python", "english"], "age": 40, "name": "qiwsir"}]

encoding的操作是比較簡(jiǎn)單的,請(qǐng)注意觀察data和data_json的不同——lang的值從元組編程了列表,還有不同:

>>> type(data_json)
<type 'str'>
>>> type(data)
<type 'list'>

將python對(duì)象轉(zhuǎn)化為json類型,是按照下表所示對(duì)照關(guān)系轉(zhuǎn)化的:

python==> json
dict object
list, tuple array
str, unicode string
int, long, float number
True true
False false
None null

decoding: loads()

decoding的過程也像上面一樣簡(jiǎn)單:

>>> new_data = json.loads(data_json)
>>> new_data
[{u'lang': [u'python', u'english'], u'age': 40, u'name': u'qiwsir'}]

需要注意的是,解碼之后,并沒有將元組還原。

解碼的數(shù)據(jù)類型對(duì)應(yīng)關(guān)系:

json==> python
object dict
array list
string unicode
number(int) int, long
number(real) float
true True
false False
null None

對(duì)人友好

上面的data都不是很長(zhǎng),還能湊合閱讀,如果很長(zhǎng)了,閱讀就有難度了。所以,json的dumps()提供了可選參數(shù),利用它們能在輸出上對(duì)人更友好(這對(duì)機(jī)器是無所謂的)。

>>> data_j = json.dumps(data, sort_keys=True, indent=2)
>>> print data_j
[
  {
    "age": 40, 
    "lang": [
      "python", 
      "english"
    ], 
    "name": "qiwsir"
  }
]

sort_keys=True意思是按照鍵的字典順序排序,indent=2是讓每個(gè)鍵值對(duì)顯示的時(shí)候,以縮進(jìn)兩個(gè)字符對(duì)齊。這樣的視覺效果好多了。

大json字符串

如果數(shù)據(jù)不是很大,上面的操作足夠了。但是,上面操作是將數(shù)據(jù)都讀入內(nèi)存,如果太大就不行了。怎么辦?json提供了load()dump()函數(shù)解決這個(gè)問題,注意,跟上面已經(jīng)用過的函數(shù)相比,是不同的,請(qǐng)仔細(xì)觀察。

>>> import tempfile    #臨時(shí)文件模塊
>>> data
[{'lang': ('python', 'english'), 'age': 40, 'name': 'qiwsir'}]
>>> f = tempfile.NamedTemporaryFile(mode='w+')
>>> json.dump(data, f)
>>> f.flush()
>>> print open(f.name, "r").read()
[{"lang": ["python", "english"], "age": 40, "name": "qiwsir"}]

自定義數(shù)據(jù)類型

一般情況下,用的數(shù)據(jù)類型都是python默認(rèn)的。但是,我們學(xué)習(xí)過類后,就知道,自己可以定義對(duì)象類型的。比如:

以下代碼參考:Json概述以及python對(duì)json的相關(guān)操作

#!/usr/bin/env python
# coding=utf-8

import json

class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def __repr__(self):
        return 'Person Object name : %s , age : %d' % (self.name,self.age)

def object2dict(obj):    #convert Person to dict
    d = {}
    d['__class__'] = obj.__class__.__name__
    d['__module__'] = obj.__module__
    d.update(obj.__dict__)
    return d

def dict2object(d):     #convert dict ot Person
    if '__class__' in d:
        class_name = d.pop('__class__')
        module_name = d.pop('__module__')
        module = __import__(module_name)
        class_ = getattr(module, class_name)
        args = dict((key.encode('ascii'), value) for key,value in d.items())    #get args
        inst = class_(**args)    #create new instance
    else:
        inst = d
    return inst

if __name__  == '__main__':
    p = Person('Peter',40)
    print p
    d = object2dict(p)
    print d
    o = dict2object(d)
    print type(o), o

    dump = json.dumps(p, default=object2dict)
    print dump
    load = json.loads(dump, object_hook=dict2object)
    print load
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)