Search code examples
pythonjsondictionaryserializationdeserialization

customized searialze and deserialize in python problem for JsonDF package - How to desearialize to a new object instance?


I am working on a JsonDF package that makes the ability to make whatever you want on Json, like :

  1. add keys to json with values
  2. delete keys from json
  3. dump values from keys in json
  4. update values for keys in json
  5. search for specific values depending on the key

I want to make the ability to serialize and deserialize forigen objects to Json, using my Json object as a parser, the problem is that the Json serializer is supposed to be a seperated object from the Json object but depending on it, but I searched a lot about a way in serializing and deserializing to pass the methods and create in the programming language itself without even creating a template object.

as an example :

if I have an object like the following

class Person:
    def __init__(self, name):
        self.name = name

the result of the serialization is :

{
    'name': 'Person',
    '__init__': {
        'params': [
            'name' 
        ],
        'self': {
             'name': 'params.name',
        }
    }
}

I have no problem with the serialzing it self, as in deserializing because I want the code to read the output Json, and recreate the first object above without having it already coded.

I wrote a code but the code already made an object Json with attrs with the values, but couldn't recreate the methods or an instance of it.

the full code of this project is on github, you can see it if you want to give a deep look about the code.

code for making instance and methods for a serialized Json like this :

{
    'name': 'Person',
    '__init__': {
        'params': [
            'name' 
        ],
        'self': {
             'name': 'params.name',
        }
    }
}

to an object like this :

class Person:
    def __init__(self, name):
        self.name = name

Solution

  • I have found the answer of that problem, but will work only in python 3.x because it depends on a package called inspect which is a bult-in package.

    btw, if you didn't found it you can download it via pip pip install inspect

    the code I made was actually works with objects only, not with an instance of the object.

    
    from JsonDF.Json.Json import Json
    
    class Serializer:
        def __init__(self, object:object):
            self.object = object
        
        def get_name(self):
            return self.object.__name__
        
        def get_object_params(self):
            params = Json('params', {}).objectiy()
            attributes = inspect.getmembers(self.object, lambda a:not(inspect.isroutine(a)))
            for a in attributes:
                if not (a[0].startswith('__') and a[0].endswith('__')):
                    params.insert(f"{a[0]}", a)
            return params
        
        def get_methods(self):
            methods = Json('methods', {}).objectiy()
            for key, value in self.object.__dict__.items():
                if callable(self.object.__dict__[key]):
                    method_name = key
                    method_params = self.get_method_params(value)
                    method_code = self.get_code(value)
                    methods.insert(f"{self.get_name()}.{method_name}", Json(f"{self.get_name()}.{method_name}", {f"{self.get_name()}.{method_name}": { 'params' : method_params, 'code': method_code }}).objectiy())
            return methods
    
    
        def get_method_params(self, method:classmethod) -> set:
            # print(method.__code__.co_varnames[:method.__code__.co_argcount])
            return (inspect.getfullargspec(method).args, inspect.getfullargspec(method).defaults)
        
        def get_code(self, method:classmethod) -> str:
            return inspect.getsource(method)
        
        def Serialize(self):
            return Json(self.get_name(), {'name': self.get_name(),
                                          'params': self.get_object_params(),
                                          'methods': self.get_methods()}).objectiy()
    

    the code I've added it to the package, but still facing a problem while working with instances the part of self.object.__name__ doesn't work, and I don't figured it out, but so far the code above works and solves the problem.

    the full code is on GitHub and the usage of it.