Python object serialization

introduction

The process of converting the state information of an object into a form that can be stored or transmitted is called sequencing Similarly, converting serialized data into corresponding objects is called deserialization This article introduces Python's two modules for serializing and deserializing objects

  • pickle
  • json

pickle

# serialize
In [19]: num = 66

In [20]: s = 'python'

In [21]: pi = 3.14

In [22]: li = [1, 2, 3]

In [27]: b_num = pickle.dumps(num)

In [28]: b_s = pickle.dumps(s)

In [29]: b_pi = pickle.dumps(pi)

In [30]: b_li = pickle.dumps(li)

In [31]: b_num
Out[31]: b'\x80\x03KB.'

In [32]: b_s
Out[32]: b'\x80\x03X\x06\x00\x00\x00pythonq\x00.'

In [33]: b_pi
Out[33]: b'\x80\x03G@\t\x1e\xb8Q\xeb\x85\x1f.'

In [34]: b_li
Out[34]: b'\x80\x03]q\x00(K\x01K\x02K\x03e.'
    
In [35]: type(b_li)
Out[35]: bytes
    
# Deserialization    
In [47]: pickle.loads(b_num)
Out[47]: 66

In [48]: pickle.loads(b_s)
Out[48]: 'python'

In [49]: pickle.loads(b_pi)
Out[49]: 3.14

In [50]: li = pickle.loads(b_li)

In [51]: li
Out[51]: [1, 2, 3]

In [52]: type(li)
Out[52]: list    

Custom objects can also be serialized

class User:
    
    def __init__(self, name, sex):
        self.name = name
        self.sex = sex
        
In [38]: user = User('hui', 'male')

In [39]: b_user = pickle.dumps(user)

In [40]: b_user
Out[40]: b'\x80\x03c__main__\nUser\nq\x00)\x81q\x01}q\x02(X\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00huiq\x04X\x03\x00\x00\x00sexq\x05X\x03\x00\x00\x00\xe7\x94\xb7q\x06ub.'

In [41]: type(b_user)
Out[41]: bytes

In [42]: user = pickle.loads(b_user)

In [43]: type(user)
Out[43]: __main__.User

In [44]: user.name
Out[44]: 'hui'

In [45]: user.sex
Out[45]: 'male'        

Note: after pickle serialization, the data is of byte type

pickle can also serialize objects, save them to a file, and then reverse order them back from the file.

import pickle

class User:
    
    def __init__(self, name, sex):
        self.name = name
        self.sex = sex
        
user = User('ithui', 'male')
f = open('user.txt', mode='wb')
pickle.dump(user, f)
f.close()

Reverse order from file back to object

In [3]: f = open('user.txt', 'rb')
   ...: user = pickle.load(f)
   ...: f.close()
   ...: 
In [4]: user
Out[4]: <__main__.User at 0x16c58ebef08>

In [5]: user.name
Out[5]: 'ithui'

In [6]: user.sex
Out[6]: 'male'

Although pickle module can serialize objects, it is only applicable to Python language, so it is not convenient for data exchange. For example, if you send the data to the front end, js cannot convert the data to what you want.

json

If we want to transfer objects between different programming languages, we must serialize the objects into a standard format, such as json, because json is a string, which can be read by all languages, and can also be easily stored on disk or transmitted through the network for data exchange.

The object represented by json string is the object of js. The built-in data types of json and Python correspond to the following:

JSON type

Python type

{}

dict

[]

list

"string"

’str 'or u' unicode '

3.14

int or float

true / false

True / False

null

None

In [7]: import json

In [8]: info_dict = {
   ...:     'name': 'hui',
   ...:     'age': 22,
   ...:     'is_admin': True,
   ...:     'hobbies': ['play chess game', 'Write code'],
   ...:     'other': None
   ...: }

In [9]: info_json = json.dumps(info_dict)

In [10]: info_json
Out[10]: '{
    		"name": "hui", 
    		"age": 22, 
             "is_admin": true, 
             "hobbies": ["\\u4e0b\\u8c61\\u68cb", "\\u5199\\u4ee3\\u7801"], 
             "other": null
        }'
   
# Corresponding deserialization
In [16]: info_d = json.loads(info_json)

In [17]: info_d
Out[17]:
{'name': 'hui',
 'age': 22,
 'is_admin': True,
 'hobbies': ['play chess game', 'Write code'],
 'other': None}

In [18]: type(info_d)
Out[18]: dict        

See if the custom class object can be json serialized

In [21]: import json

In [22]: class User:
    ...:
    ...:     def __init__(self, name, sex):
    ...:         self.name = name
    ...:         self.sex = sex
    ...:

In [23]: user = User('ithui', 'male')

In [24]: json.dumps(user)
    
TypeError: Object of type User is not JSON serializable    

An error is reported, saying that the User object cannot be json serialized. There must be a way to turn custom objects into json.

The general idea is to first convert the User object into an object that can be serialized by json, such as dict, and then give the serializable object to the json module.

In [28]: def user2dict(obj):
    ...:     return {'name': obj.name, 'sex': obj.sex}
    ...:
    ...:

In [29]: user = User('ithui', 'male')

In [30]: user_dict = user2dict(user)

In [31]: user_dict
Out[31]: {'name': 'ithui', 'sex': 'male'}

In [32]: user_json = json.dumps(user_dict)

In [33]: user_json
Out[33]: '{"name": "ithui", "sex": "\\u7537"}'

You can also specify a converter during serialization. The optional parameter default is to turn any object into an object that can be sequenced into JSON. We only need to write a conversion function for the User and pass the function in:

In [28]: def user2dict(obj):
    ...:     return {'name': obj.name, 'sex': obj.sex}
    ...:
    ...:
        
In [34]: user_json = json.dumps(user, default=user2dict)

In [35]: user_json
Out[35]: '{"name": "ithui", "sex": "\\u7537"}'

In this way, although you can convert custom class objects into json, you need to customize different converters for different classes, which is repetitive and troublesome. Therefore, you want to use the__ dict__ Property, which is a dict object used to store instance variables. There are a few exceptions, such as definition__ slots__ Class of

In [36]: user.__dict__
Out[36]: {'name': 'ithui', 'sex': 'male'}
    
In [41]: json.dumps(user.__dict__)
Out[41]: '{"name": "ithui", "sex": "\\u7537"}'

Note: if the attribute in the object is nested with another object that cannot be directly json serialized, use__ dict__ Properties still cannot be serialized normally.

Posted by prouty on Mon, 06 Dec 2021 12:52:01 -0800