在Python中使用类实例作为参数调用方法

时间:2017-06-20 13:46:38

标签: python

假设我有以下代码

IDLE = 0
STARTED = 1
STOPPED = 2
ERRORED = 3
# additional states as needed

class StateMachine:
    def __init__(self)
        self.state = IDLE

    def start(self):
        self.state = STARTED
        # do something

    def stop(self):
        self.state = STOPPED
        # do something

    def reset(self):
        self.state = IDLE
        # do something

我们当前的接口允许客户端通过声明所需的目标状态来更改实例的状态,此时我们运行某些验证检查,然后运行适当的方法。理想情况下,我希望保持所需目标状态的字典映射到正确的方法,以避免大量无意义的if语句块。即。

if target_state = STARTED:
    instance.start()
elif target_state = STOPPED:
    instance.stop()
...

但是我不确定下面的解决方案是否被认为是好的做法(使用实例作为arg从类中调用方法感觉有些笨拙)。

state_mapping = {
    IDLE: StateMachine.reset,
    STARTED: StateMachine.start,
    ....
}

然后使用:

进行呼叫
action = state_mapping[target_state]
action(instance)
....

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

不是那么糟糕。

然而,唯一需要记住的是action是一种未绑定的方法,乍一看方法调用可能不是很明显;除了我亲自了解字典是如何定义的。

我认为更可读的替代方法是从实例调用该方法:

state_mapping = {
    IDLE: "reset",
    STARTED: "start",
    ....
}

action = state_mapping[target_state]
getattr(instance, action)()

当方法采用多个参数时,这同样会提高可读性。

答案 1 :(得分:1)

另一种选择。

当你的班级被叫做#34; StateMachine"时,也许应该有一个方法来执行状态变化?

在这种情况下,您可以在地图中使用绑定方法

class StateMachine:
    ...

    def ChangeState(self, target):
        state_mapping = { IDLE: self.reset, STARTED: self.start, ... }
        state_mapping[target]()

您可能希望处理无效的目标状态,或者只是让它引发KEY_ERROR异常。