Jika Anda ingin mengenkode anggota arbitrer enum.Enum
ke JSON dan kemudian mendekodekannya sebagai anggota enum yang sama (bukan hanya value
atribut anggota enum ), Anda dapat melakukannya dengan menulis JSONEncoder
kelas khusus , dan fungsi dekode untuk diteruskan sebagai object_hook
argumen 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_enum
fungsi bergantung pada JSON yang telah dikodekan menggunakan EnumEncoder
, atau sesuatu yang berperilaku identik dengan itu.
Pembatasan untuk anggota PUBLIC_ENUMS
diperlukan 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'}