应该在代码中实现一个小的查找表吗?

2024-06-03 08:07:40 发布

您现在位置:Python中文网/ 问答频道 /正文

users表需要记录每个用户的状态。例如:

  • 帐户尚未创建
  • 已创建帐户
  • 帐户尚未验证
  • 验证失败短信
  • 已验证帐户

这里至少有两种选择。一种是简单地拥有一个元组(或其他一些数据结构),其中包含类模块中定义的所有可用状态变量。像这样:

user_status = ("NO_ACCOUNT", 
               "ACCOUNT_CREATED", 
               "NOT_VERIFIED", 
               "VERIFICATION_FAILED_SMS", 
               "VERIFIED")

另一种方法是使用与users表具有一对多关系的数据库表:

id  status
0   "NO_ACCOUNT"
1   "ACCOUNT_CREATED"
2   "NOT_VERIFIED"
3   "VERIFICATION_FAILED_SMS"
4   "VERIFIED"

现在,这里有趣的是,在这两种情况下,users表的status字段将存储一个整数,该整数对应于编码到数据结构或数据库表中的预定义状态。在任何一种解决方案中,users表都无法与另一个表区分开来。你知道吗

数据库版本将确保查找表中存在状态值。理论上,代码版本可以分配任何值,但实际上,每个状态评估和users表的更改都将通过一个类方法进行,如果不出现编码错误,则很难出错。你知道吗

在很大程度上,我认为这两种解决方案是等价的。你知道吗

然而,当涉及到编写代码来处理各种状态情况时,事情变得有趣起来。假设我想根据用户的状态执行操作。假设该值已被检索并分配给类中的某个地方,我可能会这样做:

if self.user_status == 0:
    print "NO_ACCOUNT: do something relevant"
elif self.user_status == 1:
    print "ACCOUNT_CREATED: do something relevant"
...
etc

换句话说,代码中有不需要的幻数。坏主意。你知道吗

我真正想要的是这样的:

if self.user_status == NO_ACCOUNT:
    print "NO_ACCOUNT: do something relevant"
elif self.user_status == ACCOUNT_CREATED:
    print "ACCOUNT_CREATED: do something relevant"
...
etc

这意味着要定义一组变量来捕获这些值(在C中,这些变量是#define,但在Python中不是这样的):

NO_ACCOUNT = 0
ACCOUNT_CREATED = 1
NOT_VERIFIED = 2
VERIFICATION_FAILED_SMS = 3
VERIFIED = 4

现在我们有了一个干净的条件集,但是我们仍然需要在每次发生变化时维护这些变量作为查找表的解决方案。也许我们添加了一个新的状态码或者删除了一个旧的状态码。你知道吗

使用查找表时的情况与此没有太大区别。如果我们不定义上述变量,我们最终会得到充满幻数的条件句,并且没有任何意义:

# This means nothing without a comment
# Prone to errors
if self.user_status == 0:

字典可能是一个更好的解决方案,而不是创建一堆变量。条件句仍然具有以下含义:

if self.user_status == status_codes["NO_ACCOUNT"]:

最后,在类初始化过程中,通过从数据库中读取查找表来建立键值对,可以加载这个字典。在这种情况下,如果修改查找表中的值,代码可能会变得“脆弱”。例如,如果我决定将“NO\u ACCOUNT”改为“ACCOUNT\u MISSING”,代码就会中断,我们必须重构才能修复。你知道吗

我理解规范化和使用DBMS来加强完整性等。我在这里思考的部分是,在决定在何处存储此类查找表时,行可能在何处:在代码中?在db里?或者两者兼而有之,加倍保养?你知道吗

我不是在寻求意见,而是在做这些选择时使用的某种算法。也许有一个真正强有力的答案,这个问题的基础上DB理论。那就更好了。你知道吗


Tags: no代码self数据库if状态status情况