Nếu bạn muốn mã hóa một enum.Enum
thành viên tùy ý thành JSON và sau đó giải mã nó thành cùng một thành viên enum (thay vì chỉ đơn giản là value
thuộc tính của thành viên enum ), bạn có thể làm như vậy bằng cách viết một JSONEncoder
lớp tùy chỉnh và một hàm giải mã để chuyển làm object_hook
đối số cho json.load()
hoặc 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
Các as_enum
chức năng dựa vào JSON đã được mã hóa sử dụng EnumEncoder
, hoặc một cái gì đó mà cư xử hệt với nó.
Hạn chế đối với các thành viên của PUBLIC_ENUMS
là cần thiết để tránh một văn bản được tạo thủ công độc hại được sử dụng, chẳng hạn như lừa mã gọi để lưu thông tin cá nhân (ví dụ: khóa bí mật được ứng dụng sử dụng) vào trường cơ sở dữ liệu không liên quan, từ đó nó có thể bị lộ (xem http://chat.stackoverflow.com/transcript/message/35999686#35999686 ).
Ví dụ sử dụng:
>>> 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'}