我有一些可以处于三种状态的东西
(比如)打开,关闭,正在运行
我会尝试通过两种方式中的一种来建模它,
is_open = Boolean(default=False)
is_running = Boolean(default=False)
并且在应用程序代码中禁止状态(比如)is_running = True,is_open = False。
我也可以尝试
state=Char(choices=("O", "C", "R"))
其中一种方法更好,有没有更好的方法呢?
编辑:我使用的是Python(和Django) 编辑2:阅读下面的答案后,我想我试图用一种适合持久化到DB的形式模拟Python中的枚举(没有它们)
答案 0 :(得分:2)
在Python中处理此问题的最简单方法是使用字符串常量。将inspect.getgeneratorstate()
添加到Python 3.2时,我们就是这样做的。该函数的可能返回值为:
GEN_CREATED = 'GEN_CREATED'
GEN_RUNNING = 'GEN_RUNNING'
GEN_SUSPENDED = 'GEN_SUSPENDED'
GEN_CLOSED = 'GEN_CLOSED'
创建一个简单的类作为常量的命名空间是另一种常见的选择(但该类的属性应该仍然是字符串而不是整数)。
在Python中,对于常量使用整数而不是字符串的收益最小。你在比较速度方面会有一点损失(但由于散列缓存和其他字符串比较优化而不多)并使用稍多的内存(但不多,因为无论目标类型如何,引用都是相同的大小),但大大简化了调试(因为您不需要将整数代码转换为有意义的状态名称 - 您只需显示字符串值)。
答案 1 :(得分:1)
实际上你只需要两个,因为在你的情况下:
closed = ! open
这取决于三个中的一个或者一个以上只能一次有效,比如开放和一起运行?如果我只允许一个州使用Enumerations
由于这个问题在Python中并不支持Enums我建议看看:How can I represent an 'Enum' in Python?所有前四个答案都很有趣,但我更喜欢第一个和第三个,来自Alexandru Nedelcu:
class State:
OPEN=1
CLOSED=2
RUNNING=3
或者Mark Harrison的答案如下:
OPEN, CLOSED, RUNNING = range(3)
答案 2 :(得分:0)
根据您的语言,您可以使用枚举:
enum DoohickyState
{
Open,
Closed,
Running
}
答案 3 :(得分:0)
难以捉摸的“Tri-boolean”值。我在某个地方见过这个。
enum Bool
{
True,
False,
FileNotFound
};
答案 4 :(得分:0)
+1表示您可能需要枚举的建议。由于python不支持它们,我可能会定义一个类来封装它。这样您就可以在更新时强制执行规则。至少,它会给你与枚举相同的行为。如果合适,您还可以控制合法的州变更,例如:
class Widget:
def __init__(self, state="Closed"):
self.state=state
def open(self):
if self.state == "Closed":
self.state = "Open"
elif self.state == "Open":
pass
else:
# do whatever if trying to open in "Running" state...
def close(self):
# etc.
class ThingContainingWidget:
def __init__(self):
self.widget=Widget()
def doSomethingThatAffectsWidget(self):
self.widget.close()
# etc.
根据问题,您可能需要/想要将状态更改逻辑移动到封闭类(例如,如果状态行为也依赖于封闭类的其他属性)。但我可能会在Widget
类中保留基本验证(确保值只能打开/关闭/运行)。
有一段时间没有做任何django,但想不出有什么理由不起作用。
第h
答案 5 :(得分:0)
这是一个利用Python“属性”的好地方 - 它允许您以透明的方式将get和set方法绑定到对象属性。
这样,你的方法可以控制你想要的行为,你的代码只需要为你的状态设置True或False:
class Machine(object):
def __init__(self):
self.open = False
self._running = False
self._closed = False
def get_running(self):
return self._running
def set_running(self, val):
if not self.open and val:
raise ValueError("Cannot run if it is closed")
self._running = True
running = property(get_running, set_running)
def get_closed(self):
return self._closed
def set_closed(self, val):
if val:
self.open = False
self.running = False
self._closed = val
closed = property(get_closed, set_closed)
在python控制台上粘贴它可以快速试驾:
>>> m = Machine()
>>> m.open
False
>>> m.running
False
>>> m.running = True
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 12, in set_running
ValueError: Cannot run if it is closed
>>> m.open = True
>>> m.running = True
>>> m.closed
False
>>> m.closed = True
>>> m.open, m.running
(False, True)
>>>