Serialisierung eines Enum-Mitglieds zu JSON

Wie kann ich ein PythonEnum Mitglied an JSON serialisieren, damit ich den daraus resultierenden JSON wieder in ein Python-Objekt deserialisieren kann?

Zum Beispiel, dieser Code:

 from enum import Enum import json class Status(Enum): success = 0 json.dumps(Status.success) 

Ergibt den Fehler:

 TypeError: <Status.success: 0> is not JSON serializable 

Wie kann ich das vermeiden?

3 Solutions collect form web for “Serialisierung eines Enum-Mitglieds zu JSON”

Wenn du ein beliebiges enum.Enum Mitglied zu JSON verschlüsseln enum.Enum und es dann als das gleiche Enum-Member dekodierst (anstatt einfach das Wertattribut des Enum-Mitglieds), kannst du dies tun, indem du eine benutzerdefinierte JSONEncoder Klasse JSONEncoder und eine Decodierungsfunktion JSONEncoder Wie das object_hook Argument zu json.load() oder 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 

Die as_enum Funktion beruht darauf, dass der JSON mit EnumEncoder codiert wurde oder etwas, das sich identisch verhält.

Die Beschränkung auf Mitglieder von PUBLIC_ENUMS ist notwendig, um zu vermeiden, dass ein bösartig gestalteter Text verwendet wird, um beispielsweise einen Code zum Speichern von privaten Informationen (z. B. einen geheimen Schlüssel, der von der Anwendung verwendet wird) zu einem nicht verwandten Datenbankfeld zu verwenden, von wo aus es dann sein könnte Ausgesetzt (siehe http://chat.stackoverflow.com/transcript/message/35999686#35999686 ).

Beispiel:

 >>> 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'} 

Die richtige Antwort hängt davon ab, was Sie mit der serialisierten Version machen wollen.

Wenn du in Python zurückschreibst, findest du die Antwort von Zero .

Wenn Ihre serialisierte Version in eine andere Sprache geht, dann möchten IntEnum stattdessen stattdessen ein IntEnum verwenden, das automatisch als die entsprechende Integer serialisiert wird:

 from enum import IntEnum import json class Status(IntEnum): success = 0 failure = 1 json.dumps(Status.success) 

Und das kommt zurück:

 '0' 

Ich mochte Zero Piraeus 'Antwort, aber modifizierte es etwas für die Arbeit mit der API für Amazon Web Services (AWS) bekannt als Boto.

 class EnumEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, Enum): return obj.name return json.JSONEncoder.default(self, obj) 

Ich habe diese Methode meinem Datenmodell hinzugefügt:

  def ToJson(self) -> str: return json.dumps(self.__dict__, cls=EnumEncoder, indent=1, sort_keys=True) 

Ich hoffe das hilft jemandem.

  • Wie formatiere ich einen String mit einem Wörterbuch in python-3.x?
  • Wie lade ich Pygame für Python 3.5.1 herunter?
  • KeyError beim Versuch, auf einen Schlüsselwert aus einem verschachtelten Manager.dict zuzugreifen
  • Scipy.integrate.quad gibt falsches Ergebnis auf großen reichen
  • Schnellere Alternative zur Verwendung der `map` Funktion
  • Wie steht Anaconda mit Python?
  • Verhindern, dass Daten aus einem leeren FIFO gelöscht werden
  • Sortieren Sie eine Liste von Tupeln in aufeinanderfolgender Reihenfolge
  • Fügen Sie Leerzeichen zu Elementen der Liste hinzu
  • Python 3.4.0 mit MySQL Datenbank
  • In python, wenn eine Funktion nicht eine return-Anweisung hat, was gibt es zurück?
  • Python ist die beste Programmiersprache der Welt.