在python中重构if语句

时间:2015-08-11 08:12:20

标签: python if-statement refactoring code-cleanup

我想和你讨论一些代码。我有:

if tuple_type == Operation.START_SERVER:
    dictionary = ServersDictionary()
    dictionary.start(some_param)
elif tuple_type == Operation.STOP_SERVER:
    dictionary = ServersDictionary()
    dictionary.stop(some_param)
(...)
elif tuple_type == Operation.START_APP:
    dictionary = AppsDictionary()
    dictionary.start(some_param)
elif ...
(....)

我有27个if / elifs。通常情况下,我会进入map - function dispatcher,但是在每个if / elif后我都有两行代码和 dictionary 引用。你会建议我一些干净的解决方案来取代那些丑陋的建筑吗?

创建27个类来应用多态或27个函数听起来不太好......你怎么看?

3 个答案:

答案 0 :(得分:3)

你是对的,映射是要走的路。使用getattr从名称中访问方法:

mapping = {Operation.START_SERVER: (ServerDictionary, 'start', some_param),
           Operation.STOP_SERVER: (ServerDictionary, 'stop', some_param),
           Operation.START_APP: (AppsDictionary, 'start', some_param)}
...
cls, method, param = mapping[tuple_type]
dictionary = cls()
getattr(dictionary, method)(param)

答案 1 :(得分:1)

如果您的客户端代码可以,则可以将元信息封装到您的枚举中,这意味着您拥有枚举。这是一个例子:

class Operation(Enum):
    START_SERVER = (0, "start", ServersDictionary)
    STOP_SERVER = (1, "stop", ServersDictionary)
    START_APP = (1, "start", AppsDictionary)

然后只有一个功能来处理您的操作:

def handle_operation(operation, some_param):
    klass = operation.klass
    dictionary = klass()
    fn = getattr(dictionary, operation.value)
    fn(some_param)

这假设您使用的是您在某个问题中的Enum。在这种情况下,您需要在那里添加一行:

class Enum(object):
    __metaclass__ = EnumMeta

    def __init__(self, value):
        super(Enum, self).__init__()

        self.value, self.repr, self.klass = value[0], value[1], value[2]

    def __repr__(self):
        return str(self.repr)

然后您不需要任何案例检查,只需:

handle_operation(tuple_type)

答案 2 :(得分:1)

也许你可以用dict或tupple表示操作,比如

op = {'target': 'Servers', 'action': 'start', 'params': (arg1, arg2)}

然后您可以像

一样访问它
obj = globals()[op['target']+'Dictionary']()
getattr(obj, op['action'])(*op['params'])