I published a lib on PyPi that does that, which pushed to write a complete
readme, that I will reproduce here if anybody is interested in more
discussion about this, along with my conclusions:
Overall, it seems like the cost of maintenance is going to be
insignificant.
While the value is reduced with objects that can't be patched during
runtime such as datetime (TypeError: can't set attributes of
built-in/extension type 'datetime.datetime') that you'd need to import from
that library instead of from datetime, it still brings value in making
serialization and deserialization into the versatile and popular JSON
format easier and more reusable than with the current object_hook, by
leveraging typical object oriented programing in a very boring way that
makes it easy for anyone to grasp.
The README looks like:
Instead of:
from json import loads, dumps
from uuid import UUID, uuid4
obj = uuid4()
encoded = dumps(str(obj))
decoded = UUID(loads(encoded))
assert obj == decoded
We can do:
from jsonlight import loads, dumps
from uuid import UUID, uuid4
obj = uuid4()
encoded = dumps(obj)
decoded = loads(UUID, encoded)
assert obj == decoded
This is because jsonlight patches uuid.UUID class to add the following
methods:
- ``__jsondump__``: return a representation of self with JSON data types
- ``__jsonload__``: instantiate an object based on the result from
__jsondump__
You can see that the main difference with ``json.loads`` is that
``jsonlight.loads`` requires a type as the first argument. This is because
``jsonlight.loads`` will first call ``json.loads`` to convert the string
into a
Python object with basic JSON types, and then pass that to the type's
``__jsonload__`` function.
Other types can't be monkey patched, so you have to import them from
jsonlight
instead, which is the sad case of datetime:
from jsonlight import loads, dumps, datetime
obj = datetime.now()
assert obj == loads(datetime, dumps(obj))
You may also define ``__jsondump__`` and ``__jsonload__`` methods on your
own
classes, example:
from jsonlight import load
class YourClass:
def __init__(self, uuid=None):
self.uuid = uuid or uuid4()
def __jsondump__(self):
return dict(uuid=self.uuid)
@classmethod
def __jsonload__(cls, data):
return cls(load(UUID, data['uuid'])
# This also works, but would not illustrate how to support
recursion
# return cls(UUID(data['uuid']))
As you can see:
- you don't have to worry about calling ``__jsondump__`` on return values of
your own ``__jsondump__`` because ``jsonlight.dumps`` will do that
recursively,
- you have full control on deserialization just like with ``__setstate__``,
but if
you call jsonlight.load in there yourself then you don't have to duplicate
deserialization logic or bother calling ``__jsonload__`` on nested
objects
yourself,
Monkey-patched stdlib objects are:
- UUID
- Path
Feel free to add more.
Stdlib objects that couldn't be monkey patched, and that you have to import
from jsonlight instead are:
- datetime
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/PL3UN25ASVP5IDSAPK5RGYIBY6GKLWHW/
Code of Conduct: http://python.org/psf/codeofconduct/