【发布时间】:2020-05-03 21:33:22
【问题描述】:
所以我正在使用一个大型 Django 代码库,该代码库自始至终都使用 python 枚举,例如:
from enum import Enum
class Status(Enum):
active = 'active'
# ... later
assert some_django_model_instance.status == Status.active.value # so far so good
...当然,“.value”部分会被遗忘并一直被忽略。现在很难完全放弃枚举,尽管它们的问题多于有用。有没有办法自动检查这样的行:
assert some_django_model_instance.status == Status.active # someone forgot ".value" here!
例如,使用 mypy 或 pylint,或者可能向基本 Enum 添加一些代码/断言?问题是,Status.active 并没有真正调用任何代码,它只是返回一个类,当然该类永远不会等于 some_django_model_instance.status,它是一个字符串。
【问题讨论】:
-
不过,
assert行会抛出AssertionError。这还不足以迫使开发人员重新审视吗? -
如果您的 django 是 2.2,您可以在数据库级别 docs.djangoproject.com/en/2.2/ref/models/constraints 添加约束检查。同样在最新的 django 3.0 中有新的选择方式docs.djangoproject.com/en/3.0/ref/models/fields/…。或者您可以扩展保存方法并在保存之前验证您的数据
-
@C.Nivs 当然,这个例子是微不足道的并且会明显地爆炸,但是在具有多个服务的大型代码库中,这个错误变得更加难以手动查找。
-
如果你想限制一个类的使用/行为,元类可能值得一看
-
我只能说上面的相等性测试应该是
assert some_django_model_instance.status is Status.active,而status应该是一个枚举成员,而不是一个字符串。我已经看到很多 django-enum 问题来解释如何做到这一点。