简体   繁体   中英

python class object is not serializable

I have the following classes and function.

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)

I validated if the output is JSON with the following link https://jsonlint.com/ .

the output:

{"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]]}

But the following code throw an error.

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

The error:

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

Any help would be super appreciated please.

You're attempting to call json.dumps on an instance of Address which the json library does not know how to handle. One simple solution is to add methods on each of your classes to make the conversion.

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))

Which prints:

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

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