鍍金池/ 教程/ Python/ 標準庫 (8)
標準庫 (4)
如何成為 Python 高手
標準庫 (6)
標準庫 (3)
類(2)
Pandas 使用 (2)
xml
用 tornado 做網(wǎng)站 (5)
文件(1)
練習
列表(3)
從小工到專家
除法
錯誤和異常 (2)
函數(shù)(1)
用 tornado 做網(wǎng)站 (7)
為做網(wǎng)站而準備
函數(shù)練習
標準庫 (8)
Pandas 使用 (1)
回顧 list 和 str
字典(1)
用 tornado 做網(wǎng)站 (3)
字符串(1)
函數(shù)(2)
寫一個簡單的程序
將數(shù)據(jù)存入文件
語句(5)
SQLite 數(shù)據(jù)庫
集成開發(fā)環(huán)境(IDE)
集合(1)
類(1)
用 tornado 做網(wǎng)站 (6)
用 tornado 做網(wǎng)站 (2)
自省
語句(4)
錯誤和異常 (1)
用 tornado 做網(wǎng)站 (4)
集合(2)
列表(1)
標準庫 (1)
生成器
mysql 數(shù)據(jù)庫 (1)
第三方庫
實戰(zhàn)
運算符
類(3)
字典(2)
語句(1)
數(shù)和四則運算
語句(2)
文件(2)
MySQL 數(shù)據(jù)庫 (2)
電子表格
迭代器
mongodb 數(shù)據(jù)庫 (1)
特殊方法 (2)
特殊方法 (1)
字符編碼
編寫模塊
用 tornado 做網(wǎng)站 (1)
標準庫 (5)
函數(shù)(4)
類(5)
字符串(2)
關(guān)于 Python 的故事
函數(shù)(3)
字符串(4)
處理股票數(shù)據(jù)
常用數(shù)學(xué)函數(shù)和運算優(yōu)先級
字符串(3)
為計算做準備
多態(tài)和封裝
類(4)
迭代
語句(3)
錯誤和異常 (3)
分析 Hello
Python 安裝
標準庫 (2)
列表(2)
元組

標準庫 (8)

json

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

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

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

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

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

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

python 標準庫中有 json 模塊,主要是執(zhí)行序列化和反序列化功能:

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

基本操作

json 模塊相對 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 的操作是比較簡單的,請注意觀察 data 和 data_json 的不同——lang 的值從元組編程了列表,還有不同:

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

將 Python 對象轉(zhuǎn)化為 json 類型,是按照下表所示對照關(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 的過程也像上面一樣簡單:

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

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

解碼的數(shù)據(jù)類型對應(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

對人友好

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

>>> 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 是讓每個鍵值對顯示的時候,以縮進兩個字符對齊。這樣的視覺效果好多了。

大 json 字符串

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

>>> import tempfile    #臨時文件模塊
>>> 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 默認的。但是,我們學(xué)習過類后,就知道,自己可以定義對象類型的。比如:

以下代碼參考:Json 概述以及 Python 對 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

總目錄   |   上節(jié):標準庫(7)   |   下節(jié):第三方庫

如果你認為有必要打賞我,請通過支付寶:qiwsir@126.com,不勝感激。

上一篇:列表(3)下一篇:錯誤和異常 (1)