在我的应用中,我正在像这样的JSON API中传递错误原因:{"ok": false, "reason": "EMAIL_ALREADY_REGISTERED"}
。但是,使用这样的纯字符串很容易受到诸如仅键入"EMAIL_REGISTERED"
或各种错字之类的错误的影响。
因此,我考虑过创建一些util以仅允许固定的一组值。我的第一个想法是枚举:
from enum import Enum
class ErrorReason(Enum):
EXCEPTION = 1
EMAIL_ALREADY_REGISTERED = 2
PASSWORD_TOO_SHORT = 3
当我键入ErrorReason.E
并检查给定值是否有效时,IDE(PyCharm)会自动为我建议可能的值,这很不错,但是,它也有缺点:
str
创建"ErrorReason.EXCEPTION"
,但我也可以执行ErrorReason.EXCEPTION.name
或.value
(获取数值),然后{{ 1}}默认情况下不支持它,因此我需要设置一个JSON序列化器子类另一种实现方式可能是:
flask.jsonify
这看起来更干净一些,class ErrorReason:
EXCEPTION = "EXCEPTION"
EMAIL_ALREADY_REGISTERED = "EMAIL_ALREADY_REGISTERED"
PASSWORD_TOO_SHORT = "PASSWORD_TOO_SHORT"
评估为简单的字符串,但也感觉不对–我必须将每个可能的值写两次,并且出于这个唯一目的的对象对我来说太过分了。
实现此目标的最佳方法是什么?或者至少,在上一个示例中创建“哑”简单对象而不输入两次所有内容,同时保留智能IDE建议的最佳方法是什么?
编辑1:我找到了一种生成给定类的方法。但是,即使我生成了注释,PyCharm仍然不会执行任何自动完成建议。
ErrorReason.EXCEPTION
有关如何动态创建类的信息,请参见this answer的开头。
答案 0 :(得分:2)
您可以使用automatic enum values并更改auto()
和__str__
的行为:
from enum import Enum, auto
class ErrorReason(str, Enum):
def _generate_next_value_(name, start, count, last_values):
return name
def __str__(self):
return self.name
EXCEPTION = auto()
EMAIL_ALREADY_REGISTERED = auto()
PASSWORD_TOO_SHORT = auto()
现在:print(ErrorReason.EMAIL_ALREADY_REGISTERED)
将只是EMAIL_ALREADY_REGISTERED
如汤姆·沃西克(Tom Wojcik)的回答所述,它也继承自str
,以使其可由json
序列化。
答案 1 :(得分:2)
有我不需要的不必要的数值
您需要它们。从字面上看,这就是您的回报。我知道您只需要name
或value
中的一个是什么意思,但最好保持不变。 auto
对此有所帮助。
在传递该值时将其序列化:str创建“ ErrorReason.EXCEPTION”,但我也可以执行ErrorReason.EXCEPTION.name或.value(获取数值),而flask.jsonify不支持默认,所以我需要设置一个JSON序列化器子类
实际上,Enum
不可序列化。
默认情况下会失败
from enum import Enum
import json
class ErrorReason(Enum):
EXCEPTION = "EXCEPTION"
EMAIL_ALREADY_REGISTERED = "EMAIL_ALREADY_REGISTERED"
PASSWORD_TOO_SHORT = "PASSWORD_TOO_SHORT"
print(json.dumps({"exc": ErrorReason.EXCEPTION}))
使用
TypeError: Object of type ErrorReason is not JSON serializable
这就是为什么鼓励将其与str
(请看父母)一起使用的原因。
from enum import Enum
import json
class ErrorReason(str, Enum):
EXCEPTION = "EXCEPTION"
EMAIL_ALREADY_REGISTERED = "EMAIL_ALREADY_REGISTERED"
PASSWORD_TOO_SHORT = "PASSWORD_TOO_SHORT"
print(json.dumps({"exc": ErrorReason.EXCEPTION}))
使用str
mixin可以很好地进行序列化。