为了账号安全,请及时绑定邮箱和手机立即绑定

字符串枚举

字符串枚举

沧海一幻觉 2023-09-12 16:51:16
在我的应用程序中,我在 JSON API 中传递错误原因,如下所示:{"ok": false, "reason": "EMAIL_ALREADY_REGISTERED"}。但是,使用像这样的纯字符串很容易出现错误,例如仅键入"EMAIL_REGISTERED"或各种拼写错误。所以我考虑创建一些实用程序来只允许固定的值集。我的第一个想法是枚举:from enum import Enum class ErrorReason(Enum):     EXCEPTION = 1     EMAIL_ALREADY_REGISTERED = 2     PASSWORD_TOO_SHORT = 3ErrorReason.E当我输入并检查给定值是否有效时,IDE(PyCharm)会自动建议我可能的值,这很棒,但是它也有缺点:有一些我不需要的不必要的数值传递此值时序列化它:str创建"ErrorReason.EXCEPTION",但我也可以执行ErrorReason.EXCEPTION.name, or .value(获取数值),并且flask.jsonify默认情况下不支持它,所以我需要设置一个 JSON 序列化器子类我还觉得这不是 Enum 的正确/预期用途另一种方法可以是:class ErrorReason:     EXCEPTION = "EXCEPTION"     EMAIL_ALREADY_REGISTERED = "EMAIL_ALREADY_REGISTERED"     PASSWORD_TOO_SHORT = "PASSWORD_TOO_SHORT"这看起来更干净一些,并且ErrorReason.EXCEPTION计算结果为简单的字符串,但它也感觉不对——我必须将每个可能的值写两次,而具有这个唯一目的的对象对我来说感觉有点过分了。实现这一目标的最佳方法是什么?或者至少,在上一个示例中创建“哑”简单对象而无需将所有内容键入两次,同时保留智能 IDE 建议的最佳方法是什么?编辑1:我找到了一种生成给定类的方法。但是,即使我生成注释,PyCharm 仍然不执行任何自动完成建议。_attrs = {"__annotations__": {}} for reason in ("EXCEPTION", "PASSWORD_TOO_SHORT", "EMAIL_ALREADY_REGISTERED"):     _attrs[reason] = reason     _attrs["__annotations__"][reason] = str     ErrorReason = type("ErrorReason", (), _attrs)有关如何动态创建类的信息,请参阅本答案的开头。
查看完整描述

2 回答

?
弑天下

TA贡献1818条经验 获得超8个赞

您可以使用自动枚举值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。


查看完整回答
反对 回复 2023-09-12
?
浮云间

TA贡献1829条经验 获得超4个赞

有一些我不需要的不必要的数值


你需要它们。这实际上就是您返回的内容。我知道您只需要 或 之一是什么意思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}))

使用 mixin 可以很好地序列化str。


查看完整回答
反对 回复 2023-09-12
  • 2 回答
  • 0 关注
  • 91 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信