skip to Main Content

I want to save a dataclass to a json file and save it, it is ok now without adding paramenter indent.

class EnhancedJSONEncoder(json.JSONEncoder):
        def default(self, o):
            if dataclasses.is_dataclass(o):
                return dataclasses.asdict(o)
            # return super().default(o)

model_json = json.dumps(model_args, cls=EnhancedJSONEncoder)

model_args is a dataclass object, take a simple example,

from dataclasses import dataclass
@dataclass
class Model_args:
    x: str
model_args = Model_args(x="bar")

However, when I add indent, for example,

model_json = json.dumps(model_args, cls=EnhancedJSONEncoder,indent=4)

it shows

raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type IntervalStrategy is not JSON serializable

I want to save to json file vertically(make it looks better)

 with open("model_args.json", "w") as f:
        f.write(model_json)

2

Answers


  1. Chosen as BEST ANSWER
    model_json = json.dumps(model_args, cls=EnhancedJSONEncoder)
    

    model_json is a string format, actually,like "{x="bar"}" if you want to save it as dict and add indent parameter, converting it to dict format firstly by json.loads()

    model_str = json.dumps(model_args, cls=EnhancedJSONEncoder)
    model_json = json.loads(model_str)
    with open(json_path, "w") as f:
        json.dump(model_json, f, indent=4)
    

  2. There is nothing wrong with your approach using json.JSONEncoder, but as a long-term solution, to avoid code bloat when introducing other (more complex) types such as datetime, I would suggest looking into an existing library such as dataclass-wizard, which provides built-in support for saving a dataclass instance to a file, e.g. such as with JSONFileWizard:

    from dataclasses import dataclass
    from dataclass_wizard import JSONFileWizard
    
    
    @dataclass
    class ModelArgs(JSONFileWizard):
        x: str
    
    
    ma = ModelArgs(x="bar")
    
    ## TODO
    json_path = './my_file.out.json'
    
    ma.to_json_file(json_path, indent=4)
    

    Contents of my_file.out.json:

    {
        "x": "bar"
    }
    

    Disclaimer: I am the creator and maintainer of this library.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search