Как сериализовать объекты, члены которых не сериализуются напрямую, но их представление str () есть? - PullRequest
2 голосов
/ 17 октября 2019

Я получаю такие диктовки, как (не зная заранее точной структуры)

{
  'a': 1,
  'id': UUID('6b3acb30-08bf-400c-bc64-bf70489e388c'),
}

Этот дикт не может быть напрямую сериализуем, но при приведении значения id к str - это:

import json
import uuid

print(json.dumps({
  'a': 1,
  'id': str(uuid.UUID('6b3acb30-08bf-400c-bc64-bf70489e388c')),
}))

# outputs {"a": 1, "id": "6b3acb30-08bf-400c-bc64-bf70489e388c"}

В общем случае, когда у меня есть элементы, которые необходимо преобразовать в str перед сериализацией, существует ли общий (питонный) способ автоматического преобразования?

Ответы [ 2 ]

3 голосов
/ 17 октября 2019

Лучшим вариантом является переопределение JSONEncoder.default метода:

class MyJSONEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, uuid.UUID):
            return str(o)
        return super().default(o)

print( MyJSONEncoder().encode(data) )

Если вы хотите упорядочить все, что не может обработать кодировщик по умолчанию, вы можете использовать следующий прием, хотя я бы рекомендовал взять на себя управлениепо типам, которые вы хотите поддерживать.

class MyJSONEncoder(json.JSONEncoder):
    def default(self, o):
        try:
            return super().default(o)
        except TypeError:
            return str(o)

print( json.dumps(data, cls=MyJSONEncoder) )

DOCS: https://docs.python.org/3/library/json.html#json.JSONEncoder.default

0 голосов
/ 17 октября 2019

Нет, нет, но вы можете проверить элементы данных по отдельности и конвертировать при необходимости. Таким образом, вам не нужно заранее знать структуру данных. Учтите следующее:

import json
import uuid

data = {
  'a': 1,
  'id': UUID('6b3acb30-08bf-400c-bc64-bf70489e388c')
}

for k, v in data.items():
    try:
        json.dumps(v)
    except TypeError:
        data[k] = str(uuid.v)

print(json.dumps(data))

# outputs {"a": 1, "id": "6b3acb30-08bf-400c-bc64-bf70489e388c"}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...