python進程中的實例和json格式的字符串之間的映射關系是非常直接的,相當於同一個概念被編碼成不同的表示:
stream in json form ----json.loads(str)-----> python object
stream in json form <----json.dumps(obj)----- python object
不過需注意類型的匹配,否則會報錯。比如說json格式中大括號中的鍵值應當寫成字符串。概念上json文本和python數據類型之間的對應關系是:
有沒有覺得實在是太簡單了!當然很重要的原因在於,json格式本身能很好的表達對象的概念。
PS: encode和decode這兩個詞的含義並沒有明顯的界限,都表示把同一個概念用不同的形式來表示。encode一般表示把概念在內存中的表示轉換成在外存中的表示,decode則相反。
dumps()的參數
json.dumps()方法提供了很多好用的參數可供選擇,比較常用的有sort_keys,separators,indent等參數。
參數值 sort_keys=True 表示對dict對象進行排序,我們知道默認dict是無序存放的。
參數值 indent=4 是縮進的意思,它可以使得數據存儲的格式變得更加優雅,json格式的字符串的逗號后具有換行符,花括號和中括號中的內容有縮進。當然,輸出的數據被格式化之后,變得可讀性更強,但是卻是通過增加一些冗余的空白格來進行填充的。json主要是作為一種數據通信的格式存在的,而網絡通信是很在乎數據的大小的,無用的空格會占據很多通信帶寬,所以適當時候也要對數據進行壓縮。
參數值 separator=(",", ":") 的作用是數據壓縮,去除冗余空白,減小網絡通信量。該參數傳遞是一個元組,包含分割對象的字符串。
另一個比較有用的dumps參數是skipkeys,默認為False。 dumps方法存儲dict對象時,key必須是str類型,如果出現了其他類型的話,那么會產生TypeError異常,如果開啟該參數,設為True的話,則會比較優雅的過度。
不過還是要注意,處理外部輸入輸出的語句,盡量都寫在 try: 語句塊中。
自定義對象-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) if __name__ == '__main__': p = Person('Peter',22) print p import json p = Person.Person('Peter',22) def object2dict(obj): #convert object to a dict d = {} d['__class__'] = obj.__class__.__name__ d['__module__'] = obj.__module__ d.update(obj.__dict__) return d def dict2object(d): #convert dict to object 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 d = object2dict(p) print d #{'age': 22, '__module__': 'Person', '__class__': 'Person', 'name': 'Peter'} o = dict2object(d) print type(o),o #<class 'Person.Person'> Person Object name : Peter , age : 22 dump = json.dumps(p,default=object2dict) print dump #{"age": 22, "__module__": "Person", "__class__": "Person", "name": "Peter"} load = json.loads(dump,object_hook = dict2object) print load #Person Object name : Peter , age : 22
直接實現文件的保存
dump(obj,fp) 和 obj=load(obj,fp)直接實現文件的保存,它們具有文件指針fp作為參數,dump函數需要可寫指針,load需要可讀指針。
file pointer <--------------> python object
import json jsonobj = json.load(open('jsonsource.dat', 'r')) json.dump(jsonobj, open('newjsonfile.dat', 'w'))
python中還有的pickle模塊的用法也是類似的。
下面在講解一些其他python細節知識。
python異常處理
為什么要用異常處理?因為當出現異常的時候,如果直接退出程序會導致程序太容易崩潰,如果只是簡單打印調試信息又會導致運行時不能發現准確發現錯誤,所以在正式的開發中需要異常的引發和捕獲。
異常處理包括異常的引發和捕獲。很多錯誤是可以預料的,比如處理非法的輸入,比如通信錯誤等等,我們常常需要在一些基礎服務函數中引發異常,讓上層代碼捕獲,而不是簡答的打印錯誤信息或者簡單的退出程序。
python使用 raise Exception("info") 來引發異常,用 try: except Exception, e: 來捕獲在語句塊中出現的任何異常:
try: a=2/0 b=a[2] except Exception,e: print Exception,":",e
如果僅僅是傳遞異常到更外層的代碼,也就是不做任何其他處理,則只需單獨使用 raise 關鍵字即可。
對異常的引發,要注意粒度的選擇,要不然不知道到底是哪里出了問題。
對於異常的捕獲,else 關鍵字基本上不需要用太多,直接在try中完成任務就可以了。
python字符串處理
ps:在 python中用正則表達式處理文本的編碼范式是 : regex = re.compile(oldstring) ,然后 re.__( regex[, newstring], subject) 或者 regex.__([newstring,] subject)
re是一個模塊,regex是正則表達式實例(概念上,regex和oldstring是同義詞),subject是目標字符串。.subn 和 .sub表示替換,.split 表示分隔,.match 表示匹配
如果不用正則表達式,則只能用字符串類中定義的對應函數 subject.__(oldstring, newstring)
字符串編碼與unicode類型
首先需要明確:
(1)在python中 str 和 unicode 是兩種不同的對象類型,它們兩者可以相互轉換,但兩個概念沒有依賴關系。
(2)一個 str 類型的對象,用不同的編碼方法可以有不同的二進制表示。unicode 對象常常作為轉換 str 對象編碼方式的中間角色。
(3)python進程會把引號 ' ' 解釋為創建 str 實例的操作,把字符u后面跟引號 u' ' 解釋為創建 unicode 實例的操作。
實驗一下str對象和unicode對象的相互轉換:
str轉unicode,也就是 str ----decode()----> unicode:
>>> s ="\u6d66\u53d1\u94f6\u884c"
>>> s.decode('unicode_escape')
u'\u6d66\u53d1\u94f6\u884c'
>>> print s.decode('unicode_escape')
浦發銀行
>>>
相反做法就是 str <----encode()---- unicode :
u'浦發銀行'.encode('unicode_escape')