0

I'm working on a web-server type of application and as part of multi-language communication I need to serialize objects in a JSON file. The issue is that I'd like to create a function which can take any custom object and save it at run time rather than limiting the function to what type of objects it can store based on structure.

Apologies if this question is a duplicate, however from what I have searched the other questions and answers do not seem to tackle the dynamic structure aspect of the problem, thus leading me to open this question.

The function is going to be used to communicate between PHP server code and Python scripts, hence the need for such a solution

I have attempted to use the json.dump(data,outfile) function, however the issue is that I need to convert such objects to a legal data structure first

Andrew1024
  • 152
  • 1
  • 2
  • 15

1 Answers1

1

JSON is a rigidly structured format, and Python's json module, by design, won't try to coerce types it doesn't understand.

Check out this SO answer. While __dict__ might work in some cases, it's often not exactly what you want. One option is to write one or more classes that inherit JSONEncoder and provides a method that turns your type or types into basic types that json.dump can understand.

Another option would be to write a parent class, e.g. JSONSerializable and have these data types inherit it the way you'd use an interface in some other languages. Making it an abstract base class would make sense, but I doubt that's important to your situation. Define a method on your base class, e.g. def dictify(self), and either implement it if it makes sense to have a default behavior or just have it it raise NotImplementedError.

Note that I'm not calling the method serialize, because actual serialization will be handled by json.dump.

class JSONSerializable(ABC):
    def dictify(self):
        raise NotImplementedError("Missing serialization implementation!")


class YourDataType(JSONSerializable):
    def __init__(self):
        self.something = None

    # etc etc

    def dictify(self):
        return {"something": self.something}


class YourIncompleteDataType(JSONSerializable):
    # No dictify(self) implementation
    pass

Example usage:

>>> valid = YourDataType()
>>> valid.something = "really something"
>>> valid.dictify()
{'something': 'really something'}
>>> 
>>> invalid = YourIncompleteDataType()
>>> invalid.dictify()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in dictify
NotImplementedError: Missing dictify implementation!

Basically, though: You do need to handle this yourself, possibly on a per-type basis, depending on how different your types are. It's just a matter of what method of formatting your types for serialization is the best for your use case.

kungphu
  • 4,592
  • 3
  • 28
  • 37
  • 1
    "Note that I'm not calling the method `serialize`," he said, as he forgot to update his example to _not call the method `serialize`_. Fixed. – kungphu Jul 03 '19 at 12:33