我想创建一个类,它有一个枚举作为属性。当将使用enum属性的类的实例转储为JSON字符串时,此枚举应该具有显示为人类可读值的字符串表示形式。在下面的最小工作示例中,我用三种不同的方式创建了三个枚举。
在反序列化之后,每个属性都向我们显示它来自一个枚举,除了具有字符串表示的枚举。它只是一根绳子。
如果不能实现这样的结构,我想知道为什么。
要求
如果你想测试它,你必须安装带有的jsons
和attrs
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)
order
和order_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
。