小例子

定义一个对象类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)