หากคุณต้องการเข้ารหัสenum.Enum
สมาชิกโดยพลการเป็น JSON แล้วถอดรหัสเป็นสมาชิก enum เดียวกัน (แทนที่จะเป็นเพียงvalue
แอตทริบิวต์ของสมาชิก enum ) คุณสามารถทำได้โดยการเขียน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'}