objeto - python json to dict
Cómo convertir datos JSON en un objeto Python (9)
Aquí hay una alternativa rápida y sucia de jason pickle
import json
class User:
def __init__(self, name, username):
self.name = name
self.username = username
def to_json(self):
return json.dumps(self.__dict__)
@classmethod
def from_json(cls, json_str):
json_dict = json.loads(json_str)
return cls(**json_dict)
# example usage
User("tbrown", "Tom Brown").to_json()
User.from_json(User("tbrown", "Tom Brown").to_json()).to_json()
Quiero usar Python para convertir datos JSON en un objeto Python.
Recibo objetos de datos JSON de la API de Facebook, que quiero almacenar en mi base de datos.
Mi vista actual en Django (Python) ( request.POST
contiene el JSON):
response = request.POST
user = FbApiUser(user_id = response[''id''])
user.name = response[''name'']
user.username = response[''username'']
user.save()
Esto funciona bien, pero ¿cómo manejo los objetos de datos JSON complejos?
¿No sería mucho mejor si pudiera convertir de alguna manera este objeto JSON en un objeto de Python para facilitar su uso?
Consulte la sección titulada "Especialización de decodificación de objetos JSON" en los documentos del módulo json ( http://docs.python.org/library/json.html para Python v2.7.3). Hay una sección sobre decodificación de objetos especializados. Puede usar eso para decodificar un objeto JSON en un tipo específico de Python.
Aquí hay un ejemplo:
class User(object):
def __init__(self, name, username):
self.name = name
self.username = username
import json
def object_decoder(obj):
if ''__type__'' in obj and obj[''__type__''] == ''User'':
return User(obj[''name''], obj[''username''])
return obj
json.loads(''{"__type__": "User", "name": "John Smith", "username": "jsmith"}'', object_hook=object_decoder)
print type(User)
>>>> <class ''__restricted__.User''>
Actualizar
Si desea acceder a los datos en un diccionario a través del módulo json, haga esto:
user = json.loads(''{"__type__": "User", "name": "John Smith", "username": "jsmith"}'')
print user[''name'']
print user[''username'']
Como un diccionario normal.
Esto no es código de golf, pero aquí está mi truco más corto, usando types.SimpleNamespace
como contenedor para objetos JSON.
En comparación con la principal solución de namedtuple
, es:
- probablemente más rápido / más pequeño ya que no crea una clase para cada objeto
- corta
- no hay opción de
rename
, y probablemente la misma limitación en las claves que no son identificadores válidos (utilizasetattr
debajo de las cubiertas)
Ejemplo:
from __future__ import print_function
import json
try:
from types import SimpleNamespace as Namespace
except ImportError:
# Python 2.x fallback
from argparse import Namespace
data = ''{"name": "John Smith", "hometown": {"name": "New York", "id": 123}}''
x = json.loads(data, object_hook=lambda d: Namespace(**d))
print (x.name, x.hometown.name, x.hometown.id)
He escrito un pequeño marco de serialización (de) llamado any2any que ayuda a hacer transformaciones complejas entre dos tipos de Python.
En su caso, supongo que desea json.loads
de un diccionario (obtenido con json.loads
) a un objeto complejo response.education ; response.name
response.education ; response.name
, con una estructura anidada response.education.id
, etc ... Así que eso es exactamente para lo que está hecho este framework. La documentación aún no es excelente, pero al usar any2any.simple.MappingToObject
, debería poder hacer eso muy fácilmente. Por favor pregunta si necesitas ayuda.
Modificando la respuesta @DS un poco, para cargar desde un archivo:
def _json_object_hook(d): return namedtuple(''X'', d.keys())(*d.values())
def load_data(file_name):
with open(file_name, ''r'') as file_data:
return file_data.read().replace(''/n'', '''')
def json2obj(file_name): return json.loads(load_data(file_name), object_hook=_json_object_hook)
Una cosa: esto no puede cargar elementos con números por delante. Me gusta esto:
{
"1_first_item": {
"A": "1",
"B": "2"
}
}
Porque "1_first_item" no es un nombre de campo python válido.
Para objetos complejos, puede usar JSON Pickle
Biblioteca de Python para serializar cualquier gráfico de objetos arbitrarios en JSON. Puede tomar casi cualquier objeto de Python y convertir el objeto en JSON. Además, puede reconstituir el objeto nuevamente en Python.
Puedes hacerlo en una línea, usando namedtuple
y object_hook
:
import json
from collections import namedtuple
data = ''{"name": "John Smith", "hometown": {"name": "New York", "id": 123}}''
# Parse JSON into an object with attributes corresponding to dict keys.
x = json.loads(data, object_hook=lambda d: namedtuple(''X'', d.keys())(*d.values()))
print x.name, x.hometown.name, x.hometown.id
o, para reutilizar esto fácilmente:
def _json_object_hook(d): return namedtuple(''X'', d.keys())(*d.values())
def json2obj(data): return json.loads(data, object_hook=_json_object_hook)
x = json2obj(data)
Si desea que maneje claves que no son buenos nombres de atributos, consulte el parámetro de rename
namedtuple
.
Puedes intentar esto:
class User(object):
def __init__(self, name, username, *args, **kwargs):
self.name = name
self.username = username
import json
j = json.loads(your_json)
u = User(**j)
Simplemente crea un nuevo objeto y pasa los parámetros como un mapa.
Use el http://docs.python.org/library/json.html ( nuevo en Python 2.6 ) o el módulo simplejson
que casi siempre está instalado.