歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Python實現支持JSON存儲和解析的對象

我們知道利用JSON模塊可方便的將Python基本類型(dict、list等)數據永久的存儲成文件,同時也可以通過自定義轉換函數和繼承JSON encode&decode的方法實現自定義類的存儲。本文就在前文“ Python JSON模塊”的基礎上,實現python支持JSON存儲的對象。

對象能夠采取JSON存儲和解析是有很大意義的。例如機器學習中所有分類算法的訓練過程中都存在大量的數據計算,如果每次啟動分類都需要重新訓練分類算法浪費資源且沒有效率,如果能夠將訓練產生的分類算法對象保存起來,那麼除非需要算法調優,以後只需載入即可。另一方面,對象能夠進行JSON解析和存儲也使得其可以在網絡上傳送,這在當下雲計算、分布式數據處理中都有非凡的意義。

為了實現自存儲和解析,定義對象的關鍵操作有:

0,將object_json.py copy至包中,定義對象的模塊導入object_json:import object_json。

1,__init__()函數要支持可變數量的函數調用,即要寫成__init__(self, ..., , **args)。如此定義對象才可以有除構造階段需要初始化的屬性之外的屬性。

2,對於對象構造階段必須初始化的屬性,__init__()函數中的形參必須與這些屬性名稱完全相同,如此才能通過字典‘key’: value對構造對象。

3,定義一個屬性‘__name__’--該對象實例的名稱,利用inspect模塊實現。‘__name__‘屬性主要用於產生對象存儲時默認的文件名稱。

4,定義jsonDumps()和jsonLoadTransfer()方法,通過objectLoadFromFile()完成對象JSON文件load和新對象創建。

(i)jsonDumps()用於將對象轉換成dict並通過json.dumps()將對象存儲成json文件,若用戶不指定文件名則以instancename.json為默認存儲文件。由於JSON只支持python基本類型,因此若對象中有一些其他類型(如numpy matrix),則需將其轉化成Python基本類型(如matrix.tolist()將matrix轉換成list)。

(ii)jsonLoadTransfer()用於完成數據格式的轉換,將一些對象屬性從基本類型轉化成需要的類型(如mat(list)將類型從list轉換成matrix),若對象只有Python基本類型則可以省略該方法。創建完整、可用對象過程是:

obj = objectLoadFromFile() 
obj.jsonLoadTransfer() 

下面的代碼就是支持自定義對象進行JSON存儲和解析的object_json模塊源碼。

import json 
import inspect   
import pdb 
def object2dict(obj):     
    #convert object to a dict     
    d = {'__class__':obj.__class__.__name__, '__module__':obj.__module__}     
    d.update(obj.__dict__)     
    return d 
def objectDumps2File(obj, jsonfile): 
    objDict = object2dict(obj) 
    with open(jsonfile, 'w') as f: 
        f.write(json.dumps(objDict)) 
     
def dict2object(d):     
    '''convert dict to object, the dict will be changed'''     
    if'__class__' in d:     
        class_name = d.pop('__class__')     
        module_name = d.pop('__module__')     
        module = __import__(module_name)     
        #print 'the module is:', module     
        class_ = getattr(module,class_name)     
        args = dict((key.encode('ascii'), value) for key, value in d.items()) #get args   
        #print 'the atrribute:', repr(args) 
        #pdb.set_trace() 
        inst = class_(**args) #create new instance     
    else:     
        inst = d     
    return inst 
def objectLoadFromFile(jsonFile): 
    '''load json file and generate a new object instance whose __name__ filed 
    will be 'inst' ''' 
    with open(jsonFile) as f: 
        objectDict =json.load(f) 
    obj = dict2object(objectDict) 
    return obj 
#test function     
if __name__  == '__main__': 
    class Person(object):     
        def __init__(self,name,age, **args): 
            obj_list = inspect.stack()[1][-2] 
            self.__name__ = obj_list[0].split('=')[0].strip()#object instance name 
            self.name = name     
            self.age = age 
             
        def __repr__(self):     
            return 'Person Object name : %s , age : %d' % (self.name,self.age) 
        def say(self): 
            #d = inspect.stack()[1][-2] 
            #print d[0].split('.')[0].strip() 
            return self.__name__ 
        def jsonDumps(self, filename=None): 
            '''essential transformation to Python basic type in order to 
            store as json. dumps as objectname.json if filename missed ''' 
            if not filename: 
                jsonfile = self.__name__+'.json' 
            else: jsonfile = filename 
            objectDumps2File(self, jsonfile) 
         
        def jsonLoadTransfer(self):#TBD 
            '''essential transformation to object required type,such as 
            numpy matrix.call this function after newobject = objectLoadFromFile(jsonfile)''' 
            pass 
 
    p = Person('Aidan',22)       
    #json.dumps(p)#error will be throwed 
     
    #objectDumps2File(p,'Person.json') 
    p.jsonDumps() 
    p_l = objectLoadFromFile('p.json') 
       
    print 'the decoded obj type: %s, obj:%s' % (type(p_l),repr(p_l)) 

Python類有新舊兩種,py 2.2 後類定義繼承 object 的目的是使這個類成為 new style class, 沒有繼承 object 的為傳統classic class(最終也會繼承object)。

類定義中如下兩種方法:

class Person(): 
class Person(object) 

其區別在於:

若創建新的Person instanc test,則type(test)的輸出分別為:

<type 'instance'> 
<class '__main__.Person'> 

inspect 模塊提供了一系列自省函數,它可以獲取模塊,類,方法,函數,traceback,幀對象,代碼對象的信息。常用的方法getmembers,ismodule,getcallargs,isclass等,更多詳細信息參見http://docs.python.org/library/inspect.html。

--------------------------------------分割線 --------------------------------------

Struts中異步傳送XML和JSON類型的數據 http://www.linuxidc.com/Linux/2013-08/88247.htm

Linux下JSON庫的編譯及代碼測試 http://www.linuxidc.com/Linux/2013-03/81607.htm

jQuery 獲取JSON數據[$.getJSON方法] http://www.linuxidc.com/Linux/2013-03/81673.htm

用jQuery以及JSON包將表單數據轉為JSON字符串 http://www.linuxidc.com/Linux/2013-01/77560.htm

在C語言中解析JSON配置文件 http://www.linuxidc.com/Linux/2014-05/101822.htm

--------------------------------------分割線 --------------------------------------

Copyright © Linux教程網 All Rights Reserved