代码:
def jsonToStr(jsonDict, indent=2): return json.dumps(jsonDict, indent=2, ensure_ascii=False) |
去把一个对象,其中属性中包含一个自定义的enum对象:
class RatingType(enum.Enum): NoStar = “NoStar” OneStar = “OneStar” TwoStar = “TwoStar” ThreeStar = “ThreeStar” FourStar = “FourStar” FiveStar = “FiveStar” |
去序列化为JSON字符串,结果出错了:
auto convert json dict into string <div–<—————————————————————————— Traceback (most recent call last): File “/root/Envs/RunningFast/lib/python2.7/site-packages/gevent/pywsgi.py”, line 884, in handle_one_response self.run_application() File “/root/Envs/RunningFast/lib/python2.7/site-packages/geventwebsocket/handler.py”, line 88, in run_application return super(WebSocketHandler, self).run_application() File “/root/Envs/RunningFast/lib/python2.7/site-packages/gevent/pywsgi.py”, line 870, in run_application self.result = self.application(self.environ, self.start_response) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask/app.py”, line 2000, in __call__ return self.wsgi_app(environ, start_response) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask_sockets.py”, line 48, in __call__ return self.wsgi_app(environ, start_response) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask/app.py”, line 1991, in wsgi_app response = self.make_response(self.handle_exception(e)) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask_restful/__init__.py”, line 271, in error_router return original_handler(e) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask/app.py”, line 1567, in handle_exception reraise(exc_type, exc_value, tb) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask_restful/__init__.py”, line 268, in error_router return self.handle_error(e) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask/app.py”, line 1988, in wsgi_app response = self.full_dispatch_request() File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask/app.py”, line 1641, in full_dispatch_request rv = self.handle_user_exception(e) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask_restful/__init__.py”, line 271, in error_router return original_handler(e) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask/app.py”, line 1544, in handle_user_exception reraise(exc_type, exc_value, tb) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask_restful/__init__.py”, line 268, in error_router return self.handle_error(e) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask/app.py”, line 1639, in full_dispatch_request rv = self.dispatch_request() File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask/app.py”, line 1625, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask_restful/__init__.py”, line 477, in wrapper resp = resource(*args, **kwargs) File “/root/RunningFast/stable/runningfast/resources/Accesstoken.py”, line 167, in decorated_function return f(*args, **kwargs) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask/views.py”, line 84, in view return self.dispatch_request(*args, **kwargs) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask_restful/__init__.py”, line 587, in dispatch_request resp = meth(*args, **kwargs) File “/root/RunningFast/stable/runningfast/resources/Task.py”, line 527, in put wsNotifyTaskCompleted(curTask) File “/root/RunningFast/stable/runningfast/resources/Websocket.py”, line 236, in wsNotifyTaskCompleted return wsNotifyTaskStatusChanged(curTask) File “/root/RunningFast/stable/runningfast/resources/Websocket.py”, line 302, in wsNotifyTaskStatusChanged wsSendUserMessage(toNotifUserId, respTaskStatusChangedDict) File “/root/RunningFast/stable/runningfast/resources/Websocket.py”, line 339, in wsSendUserMessage wsSendMessage(userWs, respInfoDict) File “/root/RunningFast/stable/runningfast/resources/Websocket.py”, line 65, in wsSendMessage respMessageStr = jsonToStr(respMsgDictOrStr) File “/root/RunningFast/stable/runningfast/common/utils.py”, line 48, in jsonToStr return json.dumps(jsonDict, indent=2, ensure_ascii=False) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask/json.py”, line 126, in dumps rv = _json.dumps(obj, **kwargs) File “/usr/local/lib/python2.7/json/__init__.py”, line 251, in dumps sort_keys=sort_keys, **kw).encode(obj) File “/usr/local/lib/python2.7/json/encoder.py”, line 209, in encode chunks = list(chunks) File “/usr/local/lib/python2.7/json/encoder.py”, line 434, in _iterencode for chunk in _iterencode_dict(o, _current_indent_level): File “/usr/local/lib/python2.7/json/encoder.py”, line 408, in _iterencode_dict for chunk in chunks: File “/usr/local/lib/python2.7/json/encoder.py”, line 408, in _iterencode_dict for chunk in chunks: File “/usr/local/lib/python2.7/json/encoder.py”, line 442, in _iterencode o = _default(o) File “/root/Envs/RunningFast/lib/python2.7/site-packages/flask/json.py”, line 83, in default return _json.JSONEncoder.default(self, o) File “/usr/local/lib/python2.7/json/encoder.py”, line 184, in default raise TypeError(repr(o) + ” is not JSON serializable”) TypeError: <RatingType.NoStar: ‘NoStar’> is not JSON serializable {‘CONTENT_LENGTH’: ‘0’, ‘CONTENT_TYPE’: ‘application/x-www-form-urlencoded’, ‘GATEWAY_INTERFACE’: ‘CGI/1.1’, ‘HTTP_ACCEPT_ENCODING’: ‘gzip’, ‘HTTP_AUTHORIZATION’: ‘o7ZuoJZ1bwPQSbageYeKFN08UJJw7Rh9’, ‘HTTP_CONNECTION’: ‘Keep-Alive’, ‘HTTP_HOST’: ‘115.29.173.126:21084’, ‘HTTP_USER_AGENT’: ‘Dalvik/1.6.0 (Linux; U; Android 4.4.4; HM 2A MIUI/V8.0.1.0.KHLCNDG)’, ‘PATH_INFO’: ‘/runningfast/api/v1.0/tasks/task-c7895fe7-be59-48ad-bbc3-b44c7187797f/users/user-74f41a28-7dba-4f5f-a202-782a774c4902/complete’, ‘QUERY_STRING’: ”, ‘REMOTE_ADDR’: ‘58.209.20.165’, ‘REMOTE_PORT’: ‘9738’, ‘REQUEST_METHOD’: ‘PUT’, ‘SCRIPT_NAME’: ”, ‘SERVER_NAME’: ‘AY140128113754462e2eZ’, ‘SERVER_PORT’: ‘21084’, ‘SERVER_PROTOCOL’: ‘HTTP/1.1’, ‘SERVER_SOFTWARE’: ‘gevent/1.1.2 gunicorn/19.6.0’, ‘werkzeug.request’: <Request ‘http://115.29.173.126:21084/runningfast/api/v1.0/tasks/task-c7895fe7-be59-48ad-bbc3-b44c7187797f/users/user-74f41a28-7dba-4f5f-a202-782a774c4902/complete’ [PUT]>, ‘wsgi.errors’: <gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7f9eed93ced0>, ‘wsgi.file_wrapper’: <class ‘gunicorn.http.wsgi.FileWrapper’>, ‘wsgi.input’: <gevent.pywsgi.Input object at 0x7f9eea8cd870>, ‘wsgi.multiprocess’: False, ‘wsgi.multithread’: True, ‘wsgi.run_once’: False, ‘wsgi.url_scheme’: ‘http’, ‘wsgi.version’: (1, 0)} failed with TypeError |
flask json TypeError is not JSON serializable
python json enum TypeError is not JSON serializable
serialization – Serialising an Enum member to JSON – Stack Overflow
->
里面的方案,貌似不错:
14 down vote accepted If you want to encode an arbitrary enum.Enum member to JSON and then decode it as the same enum member (rather than simply the enum member’s value attribute), you can do so by writing a custom JSONEncoder class, and a decoding function to pass as the object_hook argument to json.load() or json.loads(): class EnumEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, Enum): 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(globals()[name], member) else: return d The as_enum function relies on: The relevant Enum existing in the global namespace. The JSON having been encoded using EnumEncoder, or something which behaves identically to it. Example usage: >>> 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’} |
-》
不过我此处不需要这么用
因为我要去返回:
NoStar
而不是:
RatingType.NoStar
from enum import IntEnum import json class Status(IntEnum): success = 0 failure = 1 json.dumps(Status.success) |
这个方案不错
不过需要我此处:
找到的确存在:
String的Enum
这种系统自带的枚举
以及把函数改为:
class RatingType(StringEnum):
所以先去找:
【记录】寻找Python中是否有已实现好的类似于IntEnum的String的Enum
结果找到但是安装不了。
python json enum TypeError
python json dumps enum string TypeError
Python JSON Module Tutorial – w3resource
8.13. enum — Support for enumerations — Python 3.5.2 documentation
python – Enum vs String as a parameter in a function – Stack Overflow
讨论了:
对于简单的枚举,到底是直接用string还是用enum,哪个更好。
答案是:各有所长。
“
class FooBarType:
standard = 0
foo = 1
bar = 2
dict = {‘type’: FooBarType.foo}
json.dumps(dict)
class EnumIntValue(int):
def __new__(cls, name, value):
c = int.__new__(cls, int(value))
c.name = name
return c
def __repr__(self):
return self.name
def __str__(self):
return self.name
class FooBarType:
standard = EnumIntValue(‘standard’,0)
foo = EnumIntValue(‘foo’,0)
bar = EnumIntValue(‘bar’,2)
dict = {‘type’: FooBarType.foo}
json.dumps(dict)
”
也是一种办法。但是就是:
不能继承Enum了,逻辑不是足够的清晰
-》并且我要是改为这种,后续的alembic去升级数据库时,也要额外修改东西,就麻烦了。
算了,还是简单点吧:
把我自己的Enum的值,传递进去:
curTask.errandorRatingType.value
curTask.cancelByUserType.value
curTask.initiatorCancelReasonType.value
curTask.errandorCancelReasonType.value
,就不用json去解析出错了:
elif curTask.statusType == TaskStatus.Completed: eventValue = “Completed” if curTask.errandorRatingType == RatingType.NoStar: toNotifUserId = curTask.initiatorId elif curTask.errandorRatingType != RatingType.NoStar: toNotifUserId = curTask.errandorId dataValue[“errandorRatingType”] = curTask.errandorRatingType.value elif curTask.statusType == TaskStatus.Canceled: eventValue = “Canceled” dataValue[“cancelByUserType”] = curTask.cancelByUserType.value dataValue[“initiatorCancelReasonType”] = curTask.initiatorCancelReasonType.value dataValue[“errandorCancelReasonType”] = curTask.errandorCancelReasonType.value |
【总结】
此处,由于各种原因,最后是把:
已有的枚举定义,不变:
class RatingType(enum.Enum): NoStar = “NoStar” OneStar = “OneStar” TwoStar = “TwoStar” ThreeStar = “ThreeStar” FourStar = “FourStar” FiveStar = “FiveStar” |
然后在给(字典变量)传递值时,不是赋值enum枚举值,而是赋值枚举值的原始址value:
dataValue[“errandorRatingType”] = curTask.errandorRatingType.value |
这样之后再去调用:
json.dumps
时,就不会出错了。
转载请注明:在路上 » 【已解决】Python的Flask中自定义的枚举对象序列化为JSON时出错:TypeError is not JSON serializable