Home > Article > Backend Development > How to Make Custom Objects JSON Serializable without Custom Encoders?
Making Custom Objects JSON Serializable without Custom Encoders
Custom JSON serialization of non-serializable objects typically involves extending json.JSONEncoder and adding a custom encoder to json.dumps(). However, it's possible to make objects serializable using the default encoder, eliminating the need for trivial custom encoders.
Monkey-Patching the Default Encoder
The default encoder can be modified (monkey-patched) to check for a special method in objects, such as to_json(), and use it for serialization. This can be done by redefining JSONEncoder.default() in a module imported at package initialization.
Automatic Serialization using Pickle
A more comprehensive solution involves using the pickle module to pickle objects that are not standard JSON data types. This approach allows for automatic serialization of most Python objects, including user-defined class instances, without requiring special methods.
Deserialization
To deserialize pickled objects, a custom object_hook function can be provided to json.loads(). This function would unpickle objects with _python_object keys, restoring them to their original Python state.
Python 3 Portability
In Python 3, json.dumps() returns bytes objects, which require modification for pickle serialization. The pickle.dumps() result can be decoded in latin1 and then encoded back to latin1 before using pickle.loads().
Example
Consider a module called make_json_serializable2 that implements the monkey-patching and pickle-based automatic serialization:
<code class="python">from json import JSONEncoder import pickle def _default(self, obj): return {'_python_object': pickle.dumps(obj).decode('latin1')} JSONEncoder.default = _default # Replace the default method.</code>
To use this module, simply import it, and the serialization will be automatically applied:
<code class="python">import make_json_serializable2 # Custom class 'Foo' is now implicitly JSON serializable class Foo: def __init__(self, name): self.name = name # Serialize and deserialize using the default JSON encoder data = [Foo('Bar')] json_string = json.dumps(data) data2 = json.loads(json_string) print(data2 == data) # True</code>
This approach provides a straightforward and generalized method for making custom objects JSON serializable without the need for manual custom encoders.
The above is the detailed content of How to Make Custom Objects JSON Serializable without Custom Encoders?. For more information, please follow other related articles on the PHP Chinese website!