如何用字符串表示来取消枚举的序列化



我想创建一个类,它有一个枚举作为属性。当将使用enum属性的类的实例转储为JSON字符串时,此枚举应该具有显示为人类可读值的字符串表示形式。在下面的最小工作示例中,我用三种不同的方式创建了三个枚举。

在反序列化之后,每个属性都向我们显示它来自一个枚举,除了具有字符串表示的枚举。它只是一根绳子。

如果不能实现这样的结构,我想知道为什么。

要求

如果你想测试它,你必须安装带有的jsonsattrs

pip install attrs jsons

最小工作示例

在这里,您可以看到一个最小的工作示例。

import jsons
import attr
from enum import Enum
# ----------------------------------------------------
# create enumeration with the help of a dictionary
fruits = {
"PINEAPPLE": "PINEAPPLE",
"APPLE": "APPLE",
"ORANGE": "ORANGE",
"BANANA": "BANANA",
}
Fruit = Enum("FRUITS", fruits)
# ----------------------------------------------------
# create a classical enumeration

class Nut(Enum):
PEANUT = 1
HAZELNUT = 2
CASHEW = 3
WALNUT = 4

# ----------------------------------------------------
# create enumeration with a string representation

class Vegetable(str, Enum):
BROCCOLI = "BROCCOLI"
CUCUMBER = "CUCUMBER"
POTATO = "POTATO"
ONION = "ONION"

# ----------------------------------------------------
# create a class which uses the enumerations

@attr.s(auto_attribs=True, kw_only=True)
class Order(jsons.JsonSerializable):
fruit: Fruit
nut: Nut
vegetable: Vegetable

# ----------------------------------------------------
# initialize an order object, serialize and deserialize it
order = Order(fruit=Fruit.APPLE, nut=Nut.PEANUT, vegetable=Vegetable.CUCUMBER)
json_string: str = Order.dumps(order)
order_deserialised: Order = Order.loads(json_string)

orderorder_deserialised变量的结构:

order:              Order(fruit=<FRUITS.APPLE: 'APPLE'>, nut=<Nut.PEANUT: 1>, vegetable=<Vegetable.CUCUMBER: 'CUCUMBER'>)
order_deserialised: Order(fruit=<FRUITS.APPLE: 'APPLE'>, nut=<Nut.PEANUT: 1>, vegetable='CUCUMBER')

正如您所看到的,order_deserialised将蔬菜显示为字符串,而不是枚举。

也许你已经知道了,但我是为未来的读者回答的。

这个问题在JSONS 1.6.1中得到了修复,您可以在下面的示例中看到。

import enum
import jsons
class Vegetable(str, enum.Enum):
BROCCOLI = "BROCCOLI"
print(jsons.loads(jsons.dumps(Vegetable.BROCCOLI), Vegetable))
# This will output "Vegetable.BROCCOLI" with JSONS 1.6.1 or later

与其他人对这个问题的评论不同,派生出class Vegetable(str, Enum)这样的类是非常好的。在Python 3.11中添加了一个类似的想法作为StrEnum

最新更新