TypeError:UUID类型的对象不可JSON序列化

2024-06-30 07:56:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在构建一个相当大的JSON字典,其中我指定了几个UUID,如下所示:

import uuid

game['uuid'] = uuid.uuid1()

我在以下回溯中得到一个类型错误。我不确定问题是什么,因为我们可以在json对象中使用UUID

Traceback (most recent call last):
  File "/Users/claycrosby/Desktop/coding/projects/gambling/scraper/sbtesting.py", line 182, in <module>
    game_json = json.dumps(game)
  File "/opt/miniconda3/envs/ds383/lib/python3.8/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/opt/miniconda3/envs/ds383/lib/python3.8/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/opt/miniconda3/envs/ds383/lib/python3.8/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/opt/miniconda3/envs/ds383/lib/python3.8/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type UUID is not JSON serializable
[Finished in 0.5s with exit code 1]
[cmd: ['/opt/miniconda3/envs/ds383/bin/python3', '/Users/claycrosby/Desktop/coding/projects/gambling/scraper/sbtesting.py']]
[dir: /Users/claycrosby/Desktop/coding/projects/gambling/scraper]
[path: /opt/miniconda3/bin:/opt/miniconda3/condabin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/Users/claycrosby/Desktop/coding/programs/pbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin]

Tags: inpyjsonbinliblineusersfile
3条回答

那1买的答案很好。但是,如果最终不得不在太多地方对数据进行按摩以使其序列化,请考虑编写自己的JSON序列化类来为您做这件事!例如,这里有一个将IPV4地址转换为字符串的方法:

from json import JSONEncoder, dumps

class TMCSerializer(JSONEncoder):

    def default(self, value: Any) -> str:
        """JSON serialization conversion function."""

        # If it's an IP, which is not normally
        # serializable, convert to string.
        if isinstance(value, IPv4Address):
            return str(value)

        # Here you can have other handling for your
        # UUIDs, or datetimes, or whatever else you
        # have.

        # Otherwise, default to super
        return super(TMCSerializer, self).default(value)

然后你这样称呼它:

json_str = json.dumps(some_dict, cls=TMCSerializer)

将其强制转换为字符串,而不是使用uuid.UUID对象:

game['uuid'] = str(uuid.uuid1())

uuid.UUID类本身不能被JSON序列化,但对象可以用几种JSON兼容的格式表示。从help(uuid.UUID)我们可以看到这些选项(尽管字节也不是json,所以需要做更多的工作)

 |      bytes       the UUID as a 16-byte string (containing the six
 |                  integer fields in big-endian byte order)
 |  
 |      bytes_le    the UUID as a 16-byte string (with time_low, time_mid,
 |                  and time_hi_version in little-endian byte order)
 |  
 |      fields      a tuple of the six integer fields of the UUID,
 |                  which are also available as six individual attributes
 |                  and two derived attributes:
 |  
 |          time_low                the first 32 bits of the UUID
 |          time_mid                the next 16 bits of the UUID
 |          time_hi_version         the next 16 bits of the UUID
 |          clock_seq_hi_variant    the next 8 bits of the UUID
 |          clock_seq_low           the next 8 bits of the UUID
 |          node                    the last 48 bits of the UUID
 |  
 |          time                    the 60-bit timestamp
 |          clock_seq               the 14-bit sequence number
 |  
 |      hex         the UUID as a 32-character hexadecimal string
 |  
 |      int         the UUID as a 128-bit integer
 |  
 |      urn         the UUID as a URN as specified in RFC 4122

例如,如果您的API需要URN,您应该

>>> game = {'uuid': uuid.uuid1().urn}
>>> game
{'uuid': 'urn:uuid:56fabaca-0fe6-11eb-9910-c770eddca9e7'}
>>> json.dumps(game)
'{"uuid": "urn:uuid:56fabaca-0fe6-11eb-9910-c770eddca9e7"}'

相关问题 更多 >