Wenn Sie ein beliebiges Element enum.Enum
in JSON codieren und dann es als dasselbe Enum-Element (lieber als das Enum-Member value
Attribut) dekodieren möchten, können Sie das tun so durch eine benutzerdefinierte JSONEncoder
Klasse zu schreiben, und eine Decodierfunktion als object_hook
Argument json.load()
oder json.loads()
passieren:
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
Die as_enum
Funktion auf der JSON beruht codiert worden EnumEncoder
, oder etwas, das sie identisch zu verhält . Die Beschränkung auf Mitglieder von PUBLIC_ENUMS
ist notwendig, um zu verhindern, dass ein in böser Absicht erstellter Text zum Beispiel den Aufruf von Code zum Speichern privater Informationen (z. B. eines von der Anwendung verwendeten geheimen Schlüssels) in ein nicht verwandtes Datenbankfeld verwendet es könnte dann belichtet werden (siehe http://chat.stackoverflow.com/transcript/message/35999686#35999686).
Beispiel Nutzung:
>>> 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'}
@ZeroPiraeus: Gerade darüber gestolpert. Ich hatte keine Ahnung, dass ich so viele geantwortet hatte! :) –