Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
213 views
in Technique[技术] by (71.8m points)

python - JSON dumps custom formatting

I'd like to dump a Python dictionary into a JSON file with a particular custom format. For example, the following dictionary my_dict,

'text_lines': [{"line1"}, {"line2"}]

dumped with

f.write(json.dumps(my_dict, sort_keys=True, indent=2))

looks like this

  "text_lines": [
    {
      "line1"
    }, 
    {
      "line2"
    }
  ]

while I prefer that it looks like this

  "text_lines": 
  [
    {"line1"}, 
    {"line2"}
  ]

Similarly, I want the following

  "location": [
    22, 
    -8
  ]

to look like this

  "location": [22, -8]

(that is, more like a coordinate, which it is).

I know that this is a cosmetic issue, but it's important to me to preserve this formatting for easier hand editing of the file.

Any way of doing this kind of customisation? An explained example would be great (the docs did not get me very far).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Here's something that I hacked together. Not very pretty but it seems to work. You could probably handle simple dictionaries in a similar way.

class MyJSONEncoder(json.JSONEncoder):
    def __init__(self, *args, **kwargs):
        super(MyJSONEncoder, self).__init__(*args, **kwargs)
        self.current_indent = 0
        self.current_indent_str = ""

    def encode(self, o):
        #Special Processing for lists
        if isinstance(o, (list, tuple)):
            primitives_only = True
            for item in o:
                if isinstance(item, (list, tuple, dict)):
                    primitives_only = False
                    break
            output = []
            if primitives_only:
                for item in o:
                    output.append(json.dumps(item))
                return "[ " + ", ".join(output) + " ]"
            else:
                self.current_indent += self.indent
                self.current_indent_str = "".join( [ " " for x in range(self.current_indent) ])
                for item in o:
                    output.append(self.current_indent_str + self.encode(item))
                self.current_indent -= self.indent
                self.current_indent_str = "".join( [ " " for x in range(self.current_indent) ])
                return "[
" + ",
".join(output) + "
" + self.current_indent_str + "]"
        elif isinstance(o, dict):
            output = []
            self.current_indent += self.indent
            self.current_indent_str = "".join( [ " " for x in range(self.current_indent) ])
            for key, value in o.items():
                output.append(self.current_indent_str + json.dumps(key) + ": " + self.encode(value))
            self.current_indent -= self.indent
            self.current_indent_str = "".join( [ " " for x in range(self.current_indent) ])
            return "{
" + ",
".join(output) + "
" + self.current_indent_str + "}"
        else:
            return json.dumps(o)

NOTE: It's pretty much unnecessary in this code to be inheriting from JSONEncoder.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...