我有一个依赖于元组的Django模型.我想知道在我的Django程序中引用该元组中的常量的最佳实践是什么.例如,在这里,我想将" default=0
" 指定为更具可读性且不需要评论的东西.有什么建议?
Status = (
(-1, 'Cancelled'),
(0, 'Requires attention'),
(1, 'Work in progress'),
(2, 'Complete'),
)
class Task(models.Model):
status = models.IntegerField(choices=Status, default=0) # Status is 'Requires attention' (0) by default.
Run Code Online (Sandbox Code Playgroud)
编辑:
如果可能的话,我想完全避免使用一个数字.不知何故,使用字符串'需要注意'将更具可读性.
Ala*_*air 60
定义整数值的常量非常常见,如下所示:
class Task(models.Model):
CANCELLED = -1
REQUIRES_ATTENTION = 0
WORK_IN_PROGRESS = 1
COMPLETE = 2
Status = (
(CANCELLED, 'Cancelled'),
(REQUIRES_ATTENTION, 'Requires attention'),
(WORK_IN_PROGRESS, 'Work in progress'),
(COMPLETE, 'Complete'),
)
status = models.IntegerField(choices=Status, default=REQUIRES_ATTENTION)
Run Code Online (Sandbox Code Playgroud)
通过移动常量和Status
类内部,您可以保持模块的名称空间更清晰,作为奖励,您可以参考Tasks.COMPLETE
导入Tasks
模型的任何位置.
ran*_*lan 16
CANCELED, ATTENTION, WIP, COMPLETE = range(-1, 3)
Status = (
(CANCELED, 'Cancelled'),
(ATTENTION, 'Requires attention'),
(WIP, 'Work in progress'),
(COMPLETE, 'Complete'),
)
class Task(models.Model):
status = models.IntegerField(choices=Status, default=CANCELED)
Run Code Online (Sandbox Code Playgroud)
只有一个原因是您希望将它放在类命名空间之外,并且只有当这些语义由应用程序的其他模型共享时才会出现.即你无法决定他们属于哪种特定型号.
虽然在您的特定示例中似乎不是这种情况.
Lut*_*elt 12
Enum
你写道:"如果可能,我想完全避免使用一个数字." 事实上,一个命名的代表显然更加pythonic.然而,裸字符串易受错别字的影响.
Python的3.4引入了一种称为模块
enum
提供Enum
与IntEnum
伪类与此情况有所帮助.有了它,您的示例可以如下工作:
# in Python 3.4 or later:
import enum
class Status(enum.IntEnum):
Cancelled = -1,
Requires_attention = 0,
Work_in_progress = 1,
Complete = 2
def choiceadapter(enumtype):
return ((item.value, item.name.replace('_', ' ')) for item in enumtype)
class Task(models.Model):
status = models.IntegerField(choices=choiceadapter(Status),
default=Status.Requires_attention.value)
Run Code Online (Sandbox Code Playgroud)
一旦Django团队回升Enum
,它
choiceadapter
甚至会被建立在Django中.
你可以使用一个namedtuple
,使用一个常量似乎适合的永恒.;-)
>>> from collections import namedtuple
>>> Status = namedtuple('Status', ['CANCELLED', 'REQUIRES_ATTENTION', 'WORK_IN_PROGRESS', 'COMPLETE'])(*range(-1, 3))
>>> Status
Status(CANCELLED=-1, REQUIRES_ATTENTION=0, WORK_IN_PROGRESS=1, COMPLETE=2)
>>> Status.CANCELLED
-1
>>> Status[0]
-1
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Task
像Alasdair的答案一样使用属性作为常量更有意义,但是命名元组是非常便宜的替代词和不会改变的对象.如果你想在内存中有很多它们,特别方便.它们就像常规元组一样,具有描述性__repr__
和属性访问权.