如何将Python Enum成员序列化为JSON,以便将生成的JSON反序列化为Python对象?
例如,这段代码:
from enum import Enum
import json
class Status(Enum):
success = 0
json.dumps(Status.success)
Run Code Online (Sandbox Code Playgroud)
导致错误:
TypeError: <Status.success: 0> is not JSON serializable
Run Code Online (Sandbox Code Playgroud)
我怎么能避免这种情况?
要封装我使用enum模块的状态列表:
from enum import Enum
class MyEnum(Enum):
state1='state1'
state2 = 'state2'
state = MyEnum.state1
MyEnum['state1'] == state # here it works
'state1' == state # here it does not throw but returns False (fail!)
Run Code Online (Sandbox Code Playgroud)
但是,问题是我需要在脚本的许多上下文中无缝地将值用作字符串,例如:
select_query1 = select(...).where(Process.status == str(MyEnum.state1)) # works but ugly
select_query2 = select(...).where(Process.status == MyEnum.state1) # throws exeption
Run Code Online (Sandbox Code Playgroud)
如何避免调用额外的类型转换(str(state)以上)或底层值(state.value)?
对于枚举Foo,一种类型如何暗示必须包含某个枚举的成员值(而不是成员本身)的变量——例如Foo(x)将返回有效成员的值Foo?
这是我的激励示例的简化版本:
class DisbursementType(Enum):
DISBURSEMENT = "disbursement"
REFUND = "refund"
ROLLBACK = "rollback"
class SerializedDisbursement(TypedDict):
transaction_type: ???
id: str
amount: float
a: SerializedDisbursement = {"transaction_type": "refund", id: 1, amount: 4400.24}
Run Code Online (Sandbox Code Playgroud)
我真的很想避免简单地打字,transaction_type因为Literal['disbursement', 'refund', 'rollback']随着时间的推移,这很容易变得不同步。
我可以通过以下示例总结我的问题:
from enum import Enum
import json
class FooBarType(Enum):
standard = 0
foo = 1
bar = 2
dict = {'name': 'test', 'value': 'test', 'type': FooBarType.foo}
json.dumps(dict)
TypeError: <FooBarType.foo: 1> is not JSON serializable
Run Code Online (Sandbox Code Playgroud)
我收到类型错误,因为枚举不是JSON可序列化的.
我主要是实现a JsonEncoder并将其添加到json.dumps()调用中但我无法更改json.dumps()调用的行.
所以,我的问题是:
是否可以在不通过编码器的情况下在json中转储枚举json.dumps(),而是通过在FooBarType枚举中添加类方法?
我希望提取以下json:
{'name': 'test', 'value': 'test', 'type': 'foo'}
Run Code Online (Sandbox Code Playgroud)
要么
{'name': 'test', 'value': 'test', 'type': 1}
Run Code Online (Sandbox Code Playgroud) class MSG_TYPE(IntEnum):
REQUEST = 0
GRANT = 1
RELEASE = 2
FAIL = 3
INQUIRE = 4
YIELD = 5
def __json__(self):
return str(self)
class MessageEncoder(JSONEncoder):
def default(self, obj):
return obj.__json__()
class Message(object):
def __init__(self, msg_type, src, dest, data):
self.msg_type = msg_type
self.src = src
self.dest = dest
self.data = data
def __json__(self):
return dict (\
msg_type=self.msg_type, \
src=self.src, \
dest=self.dest, \
data=self.data,\
)
def ToJSON(self):
return json.dumps(self, cls=MessageEncoder)
msg = Message(msg_type=MSG_TYPE.FAIL, src=0, dest=1, data="hello world")
encoded_msg = msg.ToJSON()
decoded_msg …Run Code Online (Sandbox Code Playgroud)