简体   繁体   中英

python3, serialize / deserialize classes with generic collections

i'm trying to define class with generic collection serialize/desrialize it to/from json

import json
from typing import NamedTuple
from typing import Sequence

class ColumnDef(NamedTuple):
    name: str


class RunConfig(NamedTuple):
    columns: Sequence[ColumnDef]


def read_run_config(json_config: str) -> RunConfig:
    loaded_json = json.loads(json_config)
    return RunConfig(**loaded_json)

And test:

import unittest
from model.RunConfig import read_run_config
from model.RunConfig import ColumnDef


class TestReadRunConfig(unittest.TestCase):

    def test_read_run_config(self):
        run_config_json = """
        {
           
            "columns": [
                    {
                        "name": "id"
                    }        
                ]
        }
        """
        run_config = read_run_config(run_config_json)
        print(f"{run_config}")
        self.assertTrue(len(run_config.columns) == 1)
        self.assertEqual(run_config.columns[0], ColumnDef(name="id"))


if __name__ == '__main__':
    unittest.main()

Output:

RunConfig(columns=[{'name': 'id'}])

Failure:

AssertionError: {'name': 'id'} != ColumnDef(name='id')

Why did json lib deserialized ColumnDef as Dictionary, not is class instance?

The right class combination to make it work:

from typing import NamedTuple
from typing import List
from typing_json import loads


class RunConfig(NamedTuple):
    # Sequence didn't work, have no idea why
    columns: List[ColumnDef]

# typing_json.loads works correctly
def read_run_config(json_config: str) -> RunConfig:
    return loads(json_config, RunConfig)

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