Created
June 29, 2017 19:29
-
-
Save jlumpe/f3ee9e61e132d3dfdea1151a796f49dc to your computer and use it in GitHub Desktop.
Python JSON encoder that makes more of an effort to encode non-builtin types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from json import JSONEncoder | |
from numbers import Integral, Real | |
from collections.abc import Sequence, Mapping | |
class BetterJSONEncoder(JSONEncoder): | |
"""JSON encoder that makes more of an effort to encode non-builtin types.""" | |
def default(self, o): | |
# Check bool subclasses first, as they are also considered integers. | |
if isinstance(o, bool): | |
return bool(o) | |
# Check numeric ABCs, most specific first | |
if isinstance(o, Integral): | |
return int(o) | |
if isinstance(o, Real): | |
return float(o) | |
# Check sequence and mapping ABCs | |
if isinstance(o, Sequence): | |
return list(o) | |
if isinstance(o, Mapping): | |
return dict(o) | |
# Subclass of plain old str. Probably disjoint from all other | |
# possibilities here. | |
if isinstance(o, str): | |
return str(o) | |
# Sequence protocol | |
# Check before __index__, Numpy arrays don't subclass Sequence and | |
# have an __index__ method (which raises an error on array with more | |
# than one element). | |
if hasattr(o, '__len__') and hasattr(o, '__getitem__'): | |
return list(o) | |
# Presence of this method indicates the object is an integer (according | |
# to the standard, but Numpy arrays don't obey this). | |
if hasattr(o, '__index__'): | |
return int(o) | |
# Both float and int types have both of the following methods, so in the | |
# absence of the __index__ method prioritize __float__. | |
if hasattr(o, '__float__'): | |
return float(o) | |
if hasattr(o, '__int__'): | |
return int(o) | |
return super().default(o) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment