简体   繁体   中英

How json dumps None to empty string

I want Python's None to be encoded in json as empty string how? Below is the default behavior of json.dumps .

>>> import json
>>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
'["foo", {"bar": ["baz", null, 1.0, 2]}]'

Should I overwrite the json encoder method or is there any other way?

Input data is not that simple as in above example, on every request it could be changed to different data structure. Its difficult to write a function for changing data structure.

In the object you're encoding, use an empty string instead of a None .

Here's an untested function that walks through a series of nested dictionaries to change all None values to '' . Adding support for lists and tuples is left as an exercise to the reader.:)

import copy

def scrub(x):
    ret = copy.deepcopy(x)
    # Handle dictionaries. Scrub all values
    if isinstance(x, dict):
        for k,v in ret.items():
            ret[k] = scrub(v)
    # Handle None
    if x == None:
        ret = ''
    # Finished scrubbing
    return ret

It would be better to process the data you want to encode and replace None s with empty strings. After all, that is what you want.

Here is a slightly improved version that handles lists and tuples as well:

def scrub(x):
    # Converts None to empty string
    ret = copy.deepcopy(x)
    # Handle dictionaries, lits & tuples. Scrub all values
    if isinstance(x, dict):
        for k, v in ret.items():
            ret[k] = scrub(v)
    if isinstance(x, (list, tuple)):
        for k, v in enumerate(ret):
            ret[k] = scrub(v)
    # Handle None
    if x is None:
        ret = ''
    # Finished scrubbing
    return ret

I used it when using jsonschmea module. It seems that it cannot handle None type, and throws: jsonschema.exceptions.ValidationError: None is not of type u'string' . So this takes care of the problem.

You can actually use the json.JSONEncoder , if you have an object with lists, tuples, dicts, strings and None, you can use the class shown afterwards to replace None to empty string.

default is the method originally used to convert non json types to python, this time we use it to convert the None to empty string.

encode is used to encode the json, that's why we use it with the new default to use the new method

class NoneToEmptyJSON(json.JSONEncoder):
    def default(self, o):
        if o == None:
            o = ''
        elif type(o) == dict:
            return {self.default(key): self.default(value) for key, value in o.items()}
        elif type(o) == list or type(o) == tuple:
            return [self.default(item) for item in o]
        return o
    def encode(self, o):
        return super().encode(self.default(o))

Then instead of dump, you use encode with the class

NoneToEmptyJSON().encode(['foo', {'bar': ('baz', None, 1.0, 2)}])

Then the result is:

'["foo", {"bar": ["baz", "", 1.0, 2]}]'

You can also use params if you want indent or other things this way:

NoneToEmptyJSON(ensure_ascii=False, indent=2).encode(['foo', {'bar': ('baz', None, 1.0, 2)}])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM