임의의 enum.Enum
멤버를 JSON 으로 인코딩 한 다음 동일한 열거 형 멤버로 디코딩 하려는 경우 (단순히 열거 형 멤버의 value
속성이 아니라) 사용자 정의 JSONEncoder
클래스 를 작성하고 또는 object_hook
인수로 전달할 디코딩 함수를 작성하면 됩니다. :json.load()
json.loads()
PUBLIC_ENUMS = {
'Status': Status,
}
class EnumEncoder(json.JSONEncoder):
def default(self, obj):
if type(obj) in PUBLIC_ENUMS.values():
return {"__enum__": str(obj)}
return json.JSONEncoder.default(self, obj)
def as_enum(d):
if "__enum__" in d:
name, member = d["__enum__"].split(".")
return getattr(PUBLIC_ENUMS[name], member)
else:
return d
이 as_enum
함수는를 사용하여 인코딩 된 JSON EnumEncoder
또는 이와 동일하게 작동하는 무언가 에 의존 합니다.
의 구성원에 대한 제한 PUBLIC_ENUMS
은 악의적으로 제작 된 텍스트가 사용되는 것을 방지하기 위해 필요합니다. 예를 들어, 호출 코드를 속여 개인 정보 (예 : 응용 프로그램에서 사용하는 비밀 키)를 관련없는 데이터베이스 필드에 저장 한 다음 노출 될 수 있습니다. ( http://chat.stackoverflow.com/transcript/message/35999686#35999686 참조 ).
사용 예 :
>>> data = {
... "action": "frobnicate",
... "status": Status.success
... }
>>> text = json.dumps(data, cls=EnumEncoder)
>>> text
'{"status": {"__enum__": "Status.success"}, "action": "frobnicate"}'
>>> json.loads(text, object_hook=as_enum)
{'status': <Status.success: 0>, 'action': 'frobnicate'}