Source code for pycharmers.utils.json_utils

# coding: utf-8
import json
import datetime
import numpy as np
from .generic_utils import str_strip

[docs]class PythonCharmersJSONEncoder(json.JSONEncoder): """ Json encoder for Python data structures. Supports the following objects and types by default (``json.JSONEncoder``): +-------------------+---------------+ | Python | JSON | +===================+===============+ | dict | object | +-------------------+---------------+ | list, tuple | array | +-------------------+---------------+ | str | string | +-------------------+---------------+ | int, float | number | +-------------------+---------------+ | True | true | +-------------------+---------------+ | False | false | +-------------------+---------------+ | None | null | +-------------------+---------------+ """
[docs] def default(self, obj): """ Override this method to accommodate other types of data structures. Currently, supports the following objects and types by overriding. +-----------------------+---------------+ | Python | JSON | +=======================+===============+ | np.integar | number(int) | +-----------------------+---------------+ | np.float | number(float) | +-----------------------+---------------+ | np.ndarray | array | +-----------------------+---------------+ | np.random.RandomState | object | +-----------------------+---------------+ | datetime.datetime | string | +-----------------------+---------------+ """ # Numpy object if isinstance(obj, np.integer): return int(obj) elif isinstance(obj, np.floating): return float(obj) elif isinstance(obj, np.ndarray): return obj.tolist() elif isinstance(obj, np.random.RandomState): dict_obj = dict(zip( ["MT19937", "unsigned_integer_keys", "pos", "has_gauss", "cached_gaussian"], obj.get_state() )) return dict_obj # datetime object elif isinstance(obj, datetime.datetime): return obj.isoformat() return super().default(obj)
[docs]def dumps_json(obj, ensure_ascii=False, indent=2, cls=PythonCharmersJSONEncoder, flatten_list=True, **kwargs): """dumps Json object to String. Args: obj (dict) : Serialize ``obj`` as a JSON formatted stream. ensure_ascii (bool) : If ``ensure_ascii`` is false, then the strings written to ``fp`` can contain non-ASCII characters if they appear in strings contained in ``obj``. indent (int) : If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. cls (json.JSONEncoder) : To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``PythonCharmersJSONEncoder`` is used. flatten_list (bool) : Whether you want to flatten the list or not. Example: >>> import datetime >>> from pycharmers.utils import dumps_json >>> print(dumps_json(obj={ ... "date": datetime.datetime.now(), ... "bool" : True, ... "dual_list": [[1,2,3],[4,5,6]] >>> })) { "date": "2020-12-07T23:28:49.311962", "bool": true, "dual_list": [ [1, 2, 3], [4, 5, 6] ] } """ if flatten_list: encoder = cls(ensure_ascii=ensure_ascii, indent=indent) chunks=[]; num_brackets=0 for e in encoder.iterencode(obj, _one_shot=True): if e[0]=="[": num_brackets+=1 elif e[0]=="]": num_brackets-=1 if num_brackets>1: e = str_strip(e) chunks.append(e) text = ''.join(chunks).replace("[ ", "[") else: text = json.dumps(obj=obj, ensure_ascii=ensure_ascii, indent=indent, cls=cls, **kwargs) text = text.replace("NaN", "null") return text
[docs]def save_json(obj, file, ensure_ascii=False, indent=2, cls=PythonCharmersJSONEncoder, flatten_list=True, **kwargs): """ Save the json file with easy-to-use arguments Args: obj (dict) : Serialize ``obj`` as a JSON formatted stream. file (str) : a text or byte string giving the path of the file to be opened. ensure_ascii (bool) : If ``ensure_ascii`` is false, then the strings written to ``fp`` can contain non-ASCII characters if they appear in strings contained in ``obj``. indent (int) : If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. cls (json.JSONEncoder) : To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``PythonCharmersJSONEncoder`` is used. flatten_list (bool) : Whether you want to flatten the list or not. Example: >>> import datetime >>> from pycharmers.utils import save_json >>> save_json(obj={"date": datetime.datetime.now(), "bool" : True}, file="sample.json") >>> with open("sample.json") as f: >>> for line in f.readlines(): >>> print(line, end="") { "date": "2020-09-13T20:45:56.614838", "bool": true } """ text = dumps_json( obj=obj, ensure_ascii=ensure_ascii, indent=indent, cls=cls, flatten_list=flatten_list, **kwargs ) with open(file=file, mode="w", encoding="utf-8") as fp: fp.write(text)