On Mon, Aug 12, 2019 at 10:09 AM David Shawley firstname.lastname@example.org wrote:
On Aug 8, 2019, at 3:55 PM, Chris Angelico email@example.com wrote:
- Should there be a protocol obj.__json__() to return a string
representation of an object for direct insertion into a JSON file?
I'm inclined towards the protocol, since there are protocols for various other encoders (eg deepcopy, pickle), and it avoids the problem of json importing decimal. It can also be implemented entirely as a third-party patch, although you'd need to subclass Decimal to add that method.
I proposed something similar about a year ago . I really like the idea of a protocol for this. Especially since the other encoders already use this approach. Should I reboot this approach? The implementation was really simple .
As proposed here, this is unable to solve the original problem, because whatever's returned gets encoded (so if you return a string, it will be represented as a string). It'd need to NOT re-encode it, thus allowing an object to choose its own representation.
Minor bikeshedding: protocols like this are more usually dunders, so __json__ or __jsonformat__ would be a better spelling. I'm going to assume __json__ here, but other spellings are equally viable.
For the purposes of documentation, built-in types could be given __json__ methods, though the optimization in the C version would mean they're actually bypassed.
class int: def __json__(self): return str(self)
class float: def __json__(self): if math.isfinite(self): return str(self) return "null"
class Decimal: def __json__(self): return str(self)
It may be of value to pass the JSONEncoder instance (or a callback) to this method, which would allow the object to say "render me the way you would render this".