# **Serialització amb python** ### Què és la serialització? La serialització (marshalling) és el procés amb el qual codifiquem un objecte per tal de transmetre'l per una xarxa a qualsevol altre dispositiu. Cal considerar algunes coses: * L'objecte a transmetre (serialitzat) ha d'estar prèviament persistit d'alguna forma, ja sigui en un fitxer, als buffers de memòria, etc. * Els objectes tenen estats. Quan algun dels atributs que forma part de l'objecte canvia de valor, diem que canvia l'estat de l'objecte. La serialització codifica l'estat d'un objecte per poder-lo transmetre. * La transmissió pot fer-se com una sèrie de bytes o bé en seqüències inteligibles per l'èsser humà com XML o JSON. Així, un cop l'objecte serialitzat arriba al dipositiu de destí cal fer el procés contrari, és a dir, deserialitzar-lo. I un cop fet es torna a persistir en un altre mitjà com pot ser un fitxer, base de dades, etc. ### **Com es serialitzen objectes amb python** Segons la documentació oficial, python disposa de diferents mòduls per procedir amb la serialització com **pickle**, **marshal** i **JSON**. Aquesta mateixa documentació reconeix que pickle i marshall presenten problemes de seguretat, en tant, que existeix la possibilitat de deserialitzar contingut insegur o amb errors de format. Pel que fa a les diferències entre pickle i marshal, pickle és més potent en quant a la varietat de tipus d'objectes que pot serialitzar i deserialitzar. Centrant-nos un cop més en per què és més recomanable fer ús del mòdul JSON envers pickle, la documentació oficial de python afirma: ***els programes no construïts amb python podrien no ser capaços de deserialitzar objectes serialitzats amb pickle.*** Per tant, la forma en la qual exposarem a continuació la serialització serà amb la biblioteca de JSON. De fet, aquesta biblioteca no necessita ser instal·lada perquè normalment ja s’instal·la juntament amb la resta del llenguatge. # **4. Funcions bàsiques de la biblioteca JSON** La biblioteca ens ofereix 4 funcions bàsiques: * **json.load**: Llegeix un fitxer que conté text en format JSON i intenta decodificar el seu contingut. * **json.loads**: Decodifica una cadena de text en format JSON. * **json.dump**: Serialitza un objecte Python a un fitxer de text en format JSON (JSON file). * **json.dumps**: Serialitza un objecte Python a una cadena de text (JSON string). **Ús de json.dumps** *dumps* és particularment útil quan volem serialitzar un objecte diccionari. Els diccionaris no són més que mapes entre dos conjunts d'elements: les claus i els valors corresponents a cada clau. Un exemple de diccionari pot ser aquest: ``` client = {'nom': 'Julia', 'telefon': '650 00 55 00'} ``` Forma amb la qual el serialitzem: ``` import json # serialitza un diccionari de Python en un objecte JSON client = {'nom': 'Julia', 'telefon': '650 00 55 00'} print(json.dumps(client)) ``` Aquest print retorna una cosa semblant a això: ``` {"nom": "Julia", "telefon": "650 00 55 00"} ``` Una peculiaritat de la funció dumps és que ens permet afegir una sèrie de paràmetres per canviar el format de la sortida (i s'assembli al típic format identat JSON que ja coneixem) ``` print(json.dumps(client, indent=4, sort_keys=True)) ``` Ara el print retorna una sortida com aquesta: ``` { "nom": "Julia", "telefon": "650 00 55 00" } ``` **Ús de json.dump** Per veure la diferència amb dumps, vegem el següent codi: ``` import json client = {'nom': 'Julia', 'telefon': '650 00 55 00'} with open("sample.json", "w") as fitxer: json.dump(client, fitxer) ``` De la mateixa forma que hem fet amb *dumps*, és possible afegir a dump els paràmetres indent (per la identació) i sort_keys (per ordenar) **Ús de json.load** De forma semblant al que fa el dump, load ens permetrà deserialitzar, llegint el fitxer en format json i convertint-lo a un format "llegible": ``` import json with open("sample.json", "r") as fitxer: load = json.load(fitxer) ``` **Ús de json.loads** Loads ens permetrà fer el pas d'una cadena de text a JSON ``` import json json_object = '''{ "nombre": "Pere", "edad": 30, "cursos": ["M6", "M7", "M8"] }''' user = json.loads(json_object) print(user) ```