小例子
定义一个对象类Person
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __repr__(self): #相当于toString
return 'Person Object name : %s , age : %d' % (self.name,self.age)
if __name__ == '__main__':
p = Person('Peter',22)
print p
然后开始写我们自定义的转换函数
import importlib
import json
import gui
from gui.person import Person
p = Person('Peter',22)
class MyEncoder(json.JSONEncoder):
def default(self,obj):
#convert object to a dict
d = {}
d['__class__'] = obj.__class__.__name__
d['__module__'] = obj.__module__
d.update(obj.__dict__)
return d
class MyDecoder(json.JSONDecoder):
def __init__(self):
json.JSONDecoder.__init__(self,object_hook=self.dict2object)
def dict2object(self,d):
#convert dict to object
if'__class__' in d:
class_name = d.pop('__class__')
print("class_name:",class_name)
module_name = d.pop('__module__')
print("module_name:",module_name)
module = importlib.import_module(module_name)
class_ = getattr(module,class_name)
print(class_)
args = dict((key, value) for key, value in d.items()) #get args
print(args)
inst = gui.person.Person(**args) #create new instance
else:
inst = d
return inst
d = MyEncoder().encode(p)
print(type(d))
o = MyDecoder().decode(d)
print(type(o), o)
复杂类型类的转换
首先是多个对象类的定义,PcbDevicesInfo中嵌套DetectDeviceInfo,DetectDeviceInfo中嵌套PinInfo。
from enum import Enum
import cv2
import wx
import numpy as np
class PCBType(Enum):
"""
设备类型
"""
Template = 1
DetectionPcb = 2
class DeviceDetectResult(Enum):
"""
器件检测结果
"""
Right = 1
Error = 2
Reverse = 3
Missing = 4
Damaged = 5
Undetected = 6
Detecting = 7
UnKnown = 8
class PinDetectResult(Enum):
"""
器件检测结果
"""
Right = 1
Error = 2
Reverse = 3
Missing = 4
Damaged = 5
Undetected = 6
Detecting = 7
UnKnown = 8
class DeviceType(Enum):
"""
器件类型
"""
Unidentified = 1 # 不明确
Resistance = 2 # 电阻
Capacitance = 3 # 电容
Inductance = 4 # 电感
DIODE = 5 # 二极管
class PinInfo:
pcb_image = None
pin_result = PinDetectResult.Undetected
pin_info = "" # 记录经历了的检测
center_dir = ""
x = 0
y = 0
width = 0
height = 0
def __init__(self):
pass
def initAll(self, pcb_image, pin_result, pin_info, x, y, width, height):
self.pcb_image = pcb_image
self.pin_result = pin_result
self.pin_info = pin_info
self.x = x
self.y = y
self.width = width
self.height = height
def __repr__(self):
return 'PinInfo Object pcb_image : {} , pin_result : {} , pin_info : {} , x : {} , y : {} , width : {} , height : {} ,'\
.format(self.pcb_image, self.pin_result, self.pin_info, self.x, self.y, self.width, self.height)
class DetectDeviceInfo:
"""
检测器件信息
"""
name = None
pcb_image = None
device_type = DeviceType.Unidentified
device_model = None
detect_result = DeviceDetectResult.Undetected
detect_info = [] # 记录经历了的检测方法列表
x = 0
y = 0
width = 0
height = 0
device_pins = [] # 器件Pin列表
def __init__(self, image):
self.pcb_image = image
self.device_pins = []
self.detect_info = []
def initAll(self, pcb_image, device_type, device_model, detect_result, detect_info, device_pins, x, y, width, height):
self.pcb_image = pcb_image
self.device_type = device_type
self.device_model = device_model
self.detect_result = detect_result
self.detect_info =detect_info
self.device_pins = device_pins
self.x = x
self.y = y
self.width = width
self.height = height
def __repr__(self):
return 'DetectDeviceInfo Object name : {} , pcb_image : {} , device_type : {} , device_model : {} , detect_result : {} , detect_info : {} , x : {} , y : {} , width : {} , height : {} ,'\
.format(self.name, self.pcb_image, self.device_type, self.device_model, self.detect_result, self.detect_info, self.x, self.y, self.width, self.height)
class PcbDevicesInfo:
"""
检测器件信息
"""
device_info_list = None
image = None # Opencv BGR
pcb_image_path = None
pcb_json_path = None
show_image = None # bitmap RGB
pcb_type = PCBType.Template
device_result = DeviceDetectResult.Undetected
x = 0
y = 0
width = 0
height = 0
def __init__(self, pcb_image_path, pcb_json_path):
self.pcb_image_path = pcb_image_path
self.pcb_json_path = pcb_json_path
def initAll(self, device_info_list, pcb_image_path, pcb_json_path):
self.device_info_list = device_info_list
self.pcb_image_path = pcb_image_path
self.pcb_json_path = pcb_json_path
def __repr__(self):
return 'PcbDevicesInfo Object device_info_list : {} , image : {} , pcb_image_path : {} , pcb_json_path : {} , show_image : {} , pcb_type : {} , device_result : {} , x : {} , y : {} , width : {} , height : {} ,'\
.format(self.device_info_list, self.image, self.pcb_image_path, self.pcb_json_path, self.show_image, self.pcb_type, self.device_result, self.x, self.y, self.width, self.height)
自定义两个转换类
#obj2json
class MyEnconding(json.JSONEncoder):
def default(self, o):
if isinstance(o, DeviceType):
return str(o)
if isinstance(o, DeviceDetectResult):
return str(o)
if isinstance(o, PCBType):
return str(o)
if isinstance(o, DetectDeviceInfo):
return {
"pcb_image": o.pcb_image,
"device_type": o.device_type,
"device_model": o.device_model,
"detect_result": o.detect_result,
"detect_info": o.detect_info, # 记录经历了的检测方法列表
"x": o.x,
"y": o.y,
"width": o.width,
"height": o.height,
"device_pins": o.device_pins # 器件Pin列表
}
if isinstance(o, PinInfo):
return {
"pcb_image": o.pcb_image,
"pin_result": o.pin_result,
"pin_info": o.pin_info, # 记录经历了的检测
"x": o.x,
"y": o.y,
"width": o.width,
"height": o.height
}
if isinstance(o, PcbDevicesInfo):
return {
"device_info_list": o.device_info_list,
"pcb_image_path": o.pcb_image_path,
"pcb_json_path": o.pcb_json_path,
"pcb_type":o.pcb_type,
"device_result":o.device_result,
"x": o.x,
"y": o.y,
"width": o.width,
"height": o.height
}
#json2obj
class MyDecoding(json.JSONDecoder):
def __init__(self):
json.JSONDecoder.__init__(self,object_hook=self.dict2object)
def dict2object(self,d):
print(d)
#convert dict to object
if 'pin_result' in d:
args = dict((key, value) for key, value in d.items())
pin = PinInfo()
pin.initAll(**args)
print("**:",pin)
return pin
if 'detect_result' in d:
args = dict((key, value) for key, value in d.items())
detect = DetectDeviceInfo("123")
detect.initAll(**args)
print(detect)
return detect
if 'pcb_image_path' in d:
args = dict((key, value) for key, value in d.items())
devices = PcbDevicesInfo("123","123")
devices.initAll(**args)
print(devices)
return devices
调用方式
#obj2json 并存为本地文件
pcb_json = json.dumps(self.pcb.__dict__, cls=MyEnconding)
print(pcb_json)
print("转换完成")
filename = "extras1/wx_demo/names1.json"
with open(filename, 'w') as file_obj:
file_obj.write(pcb_json)
#json2obj 读出文件并转换为obj
with open(filename, 'r', encoding='utf8')as fp:
json_data = json.dumps(json.load(fp))
o = MyDecoding().decode(json_data)
print("11111111:",o)