JSON 데이터를 Python 객체로 변환하는 방법을 알고싶습니다.

Python을 사용하여 JSON 데이터를 Python 객체로 변환하고 싶습니다.

데이터베이스에 저장하려는 Facebook API에서 JSON 데이터 객체를받습니다.

Django (Python)의 현재보기 ( request.POSTJSON 포함) :

response = request.POST
user = FbApiUser(user_id = response['id'])
user.name = response['name']
user.username = response['username']
user.save()
  • 이것은 잘 작동하지만 복잡한 JSON 데이터 객체를 어떻게 처리합니까?
  • 이 JSON 객체를 사용하기 쉽도록 Python 객체로 변환 할 수 있다면 훨씬 좋지 않을까요?


답변

namedtuple and를 사용하여 한 줄로 할 수 있습니다 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

또는 이것을 쉽게 재사용 하려면 :

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)

속성 이름이 좋지 않은 키를 처리하려면 namedtuplerename매개 변수를 확인하십시오 .


답변

모듈 문서 에서 JSON 객체 디코딩 전문화 섹션을 확인하십시오 . 이를 사용하여 JSON 객체를 특정 Python 유형으로 디코딩 할 수 있습니다.json

예를 들면 다음과 같습니다.

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)  # -> <type 'type'>

최신 정보

json 모듈을 통해 사전의 데이터에 액세스하려면 다음을 수행하십시오.

user = json.loads('{"__type__": "User", "name": "John Smith", "username": "jsmith"}')
print user['name']
print user['username']

일반 사전처럼.


답변

이것은 코드 골프가 아니지만 types.SimpleNamespaceJSON 객체의 컨테이너로 사용 하는 가장 짧은 트릭 입니다.

최고의 namedtuple솔루션과 비교하면 다음 과 같습니다.

  • 각 객체에 대한 클래스를 만들지 않으므로 더 빠르거나 작을 수 있습니다.
  • 더 짧은
  • rename유효한 식별자 (용도가없는 키에 대한 옵션이없고, 아마 동일한 제한 setattr내부적으로)

예:

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)

답변

당신은 이것을 시도 할 수 있습니다 :

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)

새 객체를 만들고 매개 변수를 맵으로 전달하면됩니다.


답변

빠르고 더러운 json 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()

답변

복잡한 객체의 경우 JSON Pickle을 사용할 수 있습니다.

임의의 객체 그래프를 JSON으로 직렬화하기위한 Python 라이브러리 거의 모든 Python 객체를 사용하여 객체를 JSON으로 바꿀 수 있습니다. 또한 객체를 다시 파이썬으로 재구성 할 수 있습니다.


답변

Python 3.5 이상을 사용하는 경우 jsons일반 오래된 Python 객체로 직렬화 및 역 직렬화하는 데 사용할 수 있습니다 .

import jsons

response = request.POST

# You'll need your class attributes to match your dict keys, so in your case do:
response['id'] = response.pop('user_id')

# Then you can load that dict into your class:
user = jsons.load(response, FbApiUser)

user.save()

더 우아함을 위해 FbApiUser상속받을 수도 있습니다 jsons.JsonSerializable.

user = FbApiUser.from_json(response)

이 예제는 클래스가 문자열, 정수, 목록, 날짜 시간 등과 같은 Python 기본 유형으로 구성된 경우 작동합니다. jsonslib에는 사용자 정의 유형에 대한 유형 힌트가 필요합니다.