2011-02-04 6 views
3

나는 exploring the json library이고 개체를 JSON 데이터로 변환하고 다시 시도하고 있습니다. 이다object_hook을 사용하여 JSON을 구문 분석하는 이상한 동작

import json 

class Obj: 
    ''' 
    classdocs 
    ''' 

    def __init__(self,s,hello="Hello world!"): 
     ''' 
     Constructor 
     ''' 
     self.s = s 
     self.hello = hello 
    def __repr__(self): 
     return '<MyObj(%s,%s)>' % (self.s, self.hello) 

def objToJSON(obj): 
    return obj.__dict__ 

def jSONToObj(json): 
    print(json) 
    return Obj(**json) 

if __name__ == '__main__': 
    str = json.dumps(Obj("Hello","World"), default=objToJSON, sort_keys=True) 
    print(str) 
    print(json.loads(str,object_hook=jSONToObj)) 
    str = json.dumps(Obj("Text",{"a":"aaaa","b":"BBBBB","C":"ccccc"}), default=objToJSON, sort_keys=True) 
    print(str) 
    print(json.loads(str,object_hook=jSONToObj)) 

출력 그중 : :이 예제 코드를 실행하는 문제에 실행 한

{"hello": "World", "s": "Hello"} 
{'s': 'Hello', 'hello': 'World'} 
<MyObj(Hello,World)> 
{"hello": {"C": "ccccc", "a": "aaaa", "b": "BBBBB"}, "s": "Text"} 
{'a': 'aaaa', 'C': 'ccccc', 'b': 'BBBBB'} 
Traceback (most recent call last): 
    File "C:\Users\dimo414\src\test.py", line 27, in <module> 
    print(json.loads(str,object_hook=jSONToObj)) 
    File "C:\Python31\lib\json\__init__.py", line 318, in loads 
    return cls(**kw).decode(s) 
    File "C:\Python31\lib\json\decoder.py", line 339, in decode 
    obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 
    File "C:\Python31\lib\json\decoder.py", line 355, in raw_decode 
    obj, end = self.scan_once(s, idx) 
    File "C:\Users\dimo414\src\test.py", line 22, in jSONToObj 
    return Obj(**json) 
TypeError: __init__() got an unexpected keyword argument 'a' 

사전 객체의 사전에서 값 때 jSONToObj가에, 데이터가 전달 된 것 같다 전체 사전이 아닌 내부 사전. 왜 그런가요?

답변

3

jSONToObj 함수를 사용하여 오브젝트를 재구성해야한다고 지정했기 때문에 디시리얼라이저는 모든 사전이 오브젝트로 가정하고 디시리얼라이저를 호출하려고합니다. 워드 프로세서

:

object_hook는 결과 개체 리터럴 디코드 (a 딕셔너리)가 호출 될 함수 선택적이다. object_hook의 반환 값은 dict 대신 이 사용됩니다. 이 기능을 사용하여 맞춤 디코더 (예 : JSON-RPC 클래스 힌트)를 구현할 수 있습니다.

loads이 재귀 적으로 작동하고 맨 아래 계층에서 시작하기 때문에 내재 된 명령이 먼저 직렬화 복원됩니다. 객체를 직렬화 해제하기 전에 인수를 직렬화 해제해야한다는 것은 의미가 있습니다.

+0

왜 디시리얼라이저는 모든 dicts가 객체라고 가정합니까? 왜 객체에 딕트가 들어 있지 않은가? – dimo414

+0

dicts에는 유형 주석이 없기 때문에 json 함수는 결코 알 수 없습니다. 디시리얼라이저 함수'jSONToObj'는 dict와 dict이 아닌 것을 스스로 결정해야하며, 적절하게 객체 나 dict를 반환해야합니다. –

+0

그런데 최상위 수준의 개체 만 원하는 경우 JSON에서 데이터를 비 직렬화 한 다음 수동으로 결과 dict/list를 개체로 변환하는 것이 좋습니다. –

관련 문제