首页 > 解决方案 > python类对象不可序列化

问题描述

我有以下类和功能。

class Address:
    def __init__(self, a):
        self.transactions = [Transaction(tx) for tx in a['txs']]
    def __repr__(self):
        return "{"f'"transaction": {self.transactions}'"}"

class Transaction:
    def __init__(self, t):
        self.time = t['time']
        self.size = t['size']
    def __repr__(self):
        return f'[{self.time}, ' + f'{self.size}]'

def get_address(address):
    resource = 'address/{0}?format=json'.format(address)
    response = util.call_api(resource)
    json_response = json.loads(response)
    return Address(json_response)

我通过以下链接验证了输出是否为 JSON https://jsonlint.com/

输出:

{"transaction": [[1593700974, 225], [1593700792, 226], [1593700643, 224], [1593700521, 223], [1593700188, 225], [1593700128, 225], [1593700006, 225], [1593699937, 323], [1593699855, 387], [1593699795, 546], [1593699734, 226], [1593699672, 351], [1593699521, 226], [1593699180, 224], [1593698457, 257], [1593698215, 256], [1593697822, 225], [1593697762, 257], [1593697430, 226], [1593696633, 223], [1593696030, 288], [1593695968, 225], [1593695908, 294], [1593695697, 257], [1593695515, 225], [1593695364, 225], [1593695302, 223], [1593694913, 223], [1593694459, 223], [1593694186, 258], [1593693858, 223], [1593693664, 225], [1593693246, 224], [1593693002, 223], [1593692791, 223], [1593692067, 223], [1593691674, 223], [1593691554, 225], [1593690881, 225], [1593690759, 255], [1593690277, 223], [1593689883, 226], [1593689701, 226], [1593689640, 225], [1593689097, 224], [1593688967, 226], [1593688576, 224], [1593688515, 259], [1593688454, 224], [1593688302, 226]]}

但是下面的代码会抛出一个错误。

p = get_address('*******************')
frame = pd.read_json(json.dumps(p))

错误:

Traceback (most recent call last):
  File "test_explo.py", line 9, in <module>
    frame = pd.DataFrame(json.dumps(p))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Address is not JSON serializable

任何帮助将不胜感激。

标签: pythonjsonpandas

解决方案


您正在尝试调用库不知道如何处理的json.dumps实例。一个简单的解决方案是在每个类上添加方法以进行转换。Addressjson

import json

class Address(object):
    def __init__(self, a):
        self.transactions = [Transaction(tx) for tx in a['txs']]
    
    def to_json(self, **kwargs) -> str:
        transactions = [{'time': t.time, 'size': t.size} for t in self.transactions]
        return json.dumps({'txs': transactions}, **kwargs)

class Transaction(object):
    def __init__(self, t):
        self.time = t['time']
        self.size = t['size']


a = Address({'txs': [{'time': 1, 'size': 2}, {'time': 3, 'size': 4}]})
print(a.to_json(indent=2, sort_keys=True))

哪个打印:

{
  "txs": [
    {
      "size": 2,
      "time": 1
    },
    {
      "size": 4,
      "time": 3
    }
  ]
}

推荐阅读