Jika Anda ingin mengenkode anggota arbitrer enum.Enumke JSON dan kemudian mendekodekannya sebagai anggota enum yang sama (bukan hanya valueatribut anggota enum ), Anda dapat melakukannya dengan menulis JSONEncoderkelas khusus , dan fungsi dekode untuk diteruskan sebagai object_hookargumen ke json.load()atau 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
The as_enumfungsi bergantung pada JSON yang telah dikodekan menggunakan EnumEncoder, atau sesuatu yang berperilaku identik dengan itu.
Pembatasan untuk anggota PUBLIC_ENUMSdiperlukan untuk menghindari teks perusak yang digunakan untuk, misalnya, menipu kode pemanggil untuk menyimpan informasi pribadi (misalnya kunci rahasia yang digunakan oleh aplikasi) ke bidang database yang tidak terkait, dari mana kemudian dapat diekspos (lihat http://chat.stackoverflow.com/transcript/message/35999686#35999686 ).
Contoh penggunaan:
>>> 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'}