Change json.dumps behaviour : customize serialization

Question:

Imagine, I’ve got a dict {"a": "hello", "b": b"list"}

  • ‘a’ is a string
  • ‘b’ is a byte string

I would like to serialize the dict into the "json"(*) string –> ‘{"a": "hello", "b": list}’

(*) : not really json compliant

For that, i’ve written that method, it works ….

def stringify(obj):
    def my(obj):
        if isinstance(obj,bytes):
            return "<:<:%s:>:>" % obj.decode()
    return json.dumps(obj, default=my).replace('"<:<:',"").replace(':>:>"',"")

(the "<:<:" & ":>:>" are just here, to be replaced, post json serailisation, to obtain the desired result)

It’s a little be hacky, using string substitution to obtain the result … it works 😉

I ask myself, and you, if it can be done in a better/python way …
Do you have any idea ?

Asked By: manatlan

||

Answers:

In order to achieve your desired output, i.e. '{"a": "hello", "b": list}' you will need to do some ugly, but fair cosmetic changes, such as reconstructing the dictionary by yourself. As the plain old dictionary {"a": "hello", "b": list} makes no sense as a python variable (well, this specific example does, only because we’re using the built-in list, but if it was "mymethod" or anything else – it wouldn’t)

def stringify(input_dict: dict):
    for k, v in input_dict.items():
        if isinstance(v, bytes):
            input_dict[k] = v.decode()
        else:
            input_dict[k] = f'"{v}"'
    return '{' + ', '.join([f'{k}: {v}' for k, v in input_dict.items()]) + '}'

We can see that here we are reconstructing literally a dictionary using ASCII characters, not that bad, not that intuitive but nontheless works as intended.
Your solution does not work, or will not work if one of the values in the dictionary has this special set of characters <:<:.


Making this code:

d = {"a": "hello", "b": b"list"}
serialized_dict = stringify(d)
print(serialized_dict)

Output:

{a: "hello", b: list}

Which is of type str, NOT a valid JSON one.

Answered By: no_hex
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.