确保变量在任何给定时间仅处于一种状态
Ensure a variable is only at one state at any given time
假设我们模拟了出租车的运行。每辆车在任何给定时间只能处于 idle, rebalancing, serving
状态之一(仅作为示例,在我的模拟中还有更多)。任何时候,我都必须检查每辆车的状态并采取相应的行动。例如,如果车辆闲置然后接载乘客,则其状态应从 idle
变为 serving
。重要的是,在任何给定时间,车辆只能处于这些状态之一,并且其动作集也取决于该状态。
目前,我正在使用一长串 if-else
检查来执行此操作,但感觉非常天真并且很难调试。
比如主逻辑先检查一辆车的状态:
if self.should_move():
_ = _make_a_decision(t)
self.update_rebalancing(WARMUP_PHASE)
if self.is_busy():
self.keep_serving()
elif self.is_waiting_to_be_matched():
# it's sitting somewhere
self.keep_waiting()
elif self.rebalancing: # and not self.busy:
self.update_rebalancing(WARMUP_PHASE)
然后这些函数中的任何一个都会相应地更新其状态,所有包括这样的语句
self.idle = False
self.rebalancing = False
self.serving = True
self.time_idled = 0
重复较多,容易出错。
我想知道
- 有针对这种情况的编程模式
- 如果 Python 专门具有处理这种情况的功能
这是一个非常宽泛的问题,没有任何正确答案..
但要尝试提供帮助,为什么不使用 class?
class Taxi:
# One variable to hold an enum of the states.
self.state = 'idle'
# function to update the state
def setState(self, state):
self.state = state
# Functions to check the state (could have one to get the state and check later
def isIdle(self):
return self.state == 'idle'
然后出租车需要做的任何功能都可以放在 class 中,例如:
def pickupPassengers():
if self.state != 'idle':
return
self.passengers += 1
然后您创建出租车并通过 class
管理它们
taxi1 = Taxi()
taxi1.getPassengers()
有几种方法可以完成您想要的。如果每次状态更改时都必须手动更改多个变量,这可能会让人感到困惑……只需让一个变量负责状态!如果您仍然希望能够引用 Taxi.idle
、Taxi.rebalancing
等,那么您可以创建 @property
方法。当您定义它们时,它们看起来像函数,但被称为属性。
请参阅下面的示例,了解 Taxi
class 只有一个状态变量 self._state
并使用 @property
方法来 return 状态。
class Taxi:
def __init__(self, initial_state = "idle"):
self._state = initial_state
@property
def idle(self):
return self._state == "idle"
@property
def rebalancing(self):
return self._state == "rebalancing"
@property
def serving(self):
return self._state == "serving"
def serve(self):
print("\nChanging state to serving\n")
self._state = "serving"
T = Taxi() # Initialize taxi
print(f"Taxi is idle: {T.idle}")
print(f"Taxi is rebalancing: {T.rebalancing}")
print(f"Taxi is serving: {T.serving}")
T.serve()
print(f"Taxi is idle: {T.idle}")
print(f"Taxi is rebalancing: {T.rebalancing}")
print(f"Taxi is serving: {T.serving}")```
Output:
Taxi is idle: True
Taxi is rebalancing: False
Taxi is serving: False
Changing state to serving
Taxi is idle: False
Taxi is rebalancing: False
Taxi is serving: True
您的设计问题是您试图使用一系列布尔值来体现离散变量(状态)的单热编码。如果一次只需要 一个 值,自然的方法是使用单个变量。枚举类型是大多数高级语言用于此的。例如,您可以将 "idle" 编码为 0,将 "rebalancing" 编码为 1,等等
Python 代码看起来像这样:
from enum import Enum, unique, auto
@unique
class TaxiState(Enum):
IDLE = auto()
REBAL = auto()
SERVE = auto()
class Taxi():
def __init__(self):
self.state = TaxiState.IDLE
def is_busy(self):
return self.state != TaxiState.IDLE
你不用担心编码; auto
处理。您所做的就是使用枚举名称作为值。您可以像设计模型的那个方面一样编写代码。
假设我们模拟了出租车的运行。每辆车在任何给定时间只能处于 idle, rebalancing, serving
状态之一(仅作为示例,在我的模拟中还有更多)。任何时候,我都必须检查每辆车的状态并采取相应的行动。例如,如果车辆闲置然后接载乘客,则其状态应从 idle
变为 serving
。重要的是,在任何给定时间,车辆只能处于这些状态之一,并且其动作集也取决于该状态。
目前,我正在使用一长串 if-else
检查来执行此操作,但感觉非常天真并且很难调试。
比如主逻辑先检查一辆车的状态:
if self.should_move():
_ = _make_a_decision(t)
self.update_rebalancing(WARMUP_PHASE)
if self.is_busy():
self.keep_serving()
elif self.is_waiting_to_be_matched():
# it's sitting somewhere
self.keep_waiting()
elif self.rebalancing: # and not self.busy:
self.update_rebalancing(WARMUP_PHASE)
然后这些函数中的任何一个都会相应地更新其状态,所有包括这样的语句
self.idle = False
self.rebalancing = False
self.serving = True
self.time_idled = 0
重复较多,容易出错。
我想知道
- 有针对这种情况的编程模式
- 如果 Python 专门具有处理这种情况的功能
这是一个非常宽泛的问题,没有任何正确答案..
但要尝试提供帮助,为什么不使用 class?
class Taxi:
# One variable to hold an enum of the states.
self.state = 'idle'
# function to update the state
def setState(self, state):
self.state = state
# Functions to check the state (could have one to get the state and check later
def isIdle(self):
return self.state == 'idle'
然后出租车需要做的任何功能都可以放在 class 中,例如:
def pickupPassengers():
if self.state != 'idle':
return
self.passengers += 1
然后您创建出租车并通过 class
管理它们taxi1 = Taxi()
taxi1.getPassengers()
有几种方法可以完成您想要的。如果每次状态更改时都必须手动更改多个变量,这可能会让人感到困惑……只需让一个变量负责状态!如果您仍然希望能够引用 Taxi.idle
、Taxi.rebalancing
等,那么您可以创建 @property
方法。当您定义它们时,它们看起来像函数,但被称为属性。
请参阅下面的示例,了解 Taxi
class 只有一个状态变量 self._state
并使用 @property
方法来 return 状态。
class Taxi:
def __init__(self, initial_state = "idle"):
self._state = initial_state
@property
def idle(self):
return self._state == "idle"
@property
def rebalancing(self):
return self._state == "rebalancing"
@property
def serving(self):
return self._state == "serving"
def serve(self):
print("\nChanging state to serving\n")
self._state = "serving"
T = Taxi() # Initialize taxi
print(f"Taxi is idle: {T.idle}")
print(f"Taxi is rebalancing: {T.rebalancing}")
print(f"Taxi is serving: {T.serving}")
T.serve()
print(f"Taxi is idle: {T.idle}")
print(f"Taxi is rebalancing: {T.rebalancing}")
print(f"Taxi is serving: {T.serving}")```
Output:
Taxi is idle: True
Taxi is rebalancing: False
Taxi is serving: False
Changing state to serving
Taxi is idle: False
Taxi is rebalancing: False
Taxi is serving: True
您的设计问题是您试图使用一系列布尔值来体现离散变量(状态)的单热编码。如果一次只需要 一个 值,自然的方法是使用单个变量。枚举类型是大多数高级语言用于此的。例如,您可以将 "idle" 编码为 0,将 "rebalancing" 编码为 1,等等
Python 代码看起来像这样:
from enum import Enum, unique, auto
@unique
class TaxiState(Enum):
IDLE = auto()
REBAL = auto()
SERVE = auto()
class Taxi():
def __init__(self):
self.state = TaxiState.IDLE
def is_busy(self):
return self.state != TaxiState.IDLE
你不用担心编码; auto
处理。您所做的就是使用枚举名称作为值。您可以像设计模型的那个方面一样编写代码。