2017-09-13 20 views
2

부울 True 값이 1으로 변환되고 부울 False 값이 0으로 변환 된 JSON 문자열로 사전을 변환하려고합니다. 내 사용자 지정 JSONEncoder.default()가 부울을 무시하는 이유는 무엇입니까?

import json 

class MyEncoder(json.JSONEncoder): 

    def default(self, obj): 
     if isinstance(obj, bool): 
      return 1 if obj else 0 
    return super().default(obj) 

data = { 'key-a' : 'a', 'key-true' : True, 'key-false' : False } 

jsondata = json.dumps(data, cls=MyEncoder) 

print(jsondata) 

나는이 결과가되고 싶어요 ... 내가 JSONEncoder 서브 클래스를 사용하고 있지만,이 논리 값을 무시하는 것 같다 그러나

{"key-true": 1, "key-a": "a", "key-false": 0} 

, 이것은 내가 무엇을 얻을 수 있습니다 :

{"key-true": true, "key-a": "a", "key-false": false} 

json.dumps으로 전달하기 전에 프로그래밍 방식으로 데이터를 수정할 수 있지만, JSONEncoder 하위 클래스를 통해 원하는 결과를 얻을 수있는 방법이 있습니까?

답변

4

하위 클래스의 default() 메서드는 인코더가 개체를 발견 할 때만 호출되며 그렇지 않으면 직렬화하는 방법을 알지 못합니다.

불행히도 공식 documentation은 이러한 사실을 분명히하지 않습니다. 그것은 언급하지만, 클래스 생성자의 "키워드 인수"섹션에서보다는 방법에 대한 설명서에 있어요 :

가 지정된 경우, 기본이 개체에 대해 호출되는 함수를해야한다고 할 수 없습니다 그렇지 않으면 직렬화됩니다. 객체의 JSON 인코딩 가능 버전을 반환하거나 TypeError을 발생시켜야합니다. 지정하지 않으면 TypeError가 발생합니다.

이 문제는 쉽게 확인할 수 있습니다 :

JSONEncoder

>>> class Foo: pass 
... 
>>> s = json.dumps({'a': False, 'b': True, 'c': Foo()}, cls=MyEncoder) 
got Foo 
>>> s 
'{"a": false, "c": {"__Foo__": 140636444256856}, "b": true}' 
설계되지

class MyEncoder(json.JSONEncoder): 

    def default(self, obj): 
     if isinstance(obj, bool): 
      print('got bool') 
      return 1 if obj else 0 
     if isinstance(obj, Foo): 
      print('got Foo') 
      return {'__Foo__': id(obj)} 
     print('got unknown') 
     return super().default(obj) 
은 쉽게 이미 인 (직렬화하는 방법을 알고있는 객체의 직렬화를 오버라이드 (override) 할 수 있도록 좋은 점 : JSON과 같은 표준의 전체적인 점은 그들이 표준 인이라는 것입니다 ... 그렇다면 불린을 실제로 인코딩하려고한다면 정수 였으므로 가장 쉬운 방법은 질문에 제안 된대로 데이터를 사전 처리하는 것입니다.

+1

답변 감사합니다. – HippoMan