我們知道利用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等,
以上是Python實作支援JSON儲存與解析的對象的詳細內容。更多資訊請關注PHP中文網其他相關文章!