在python中重构if语句

在python中重构if语句,python,if-statement,refactoring,code-cleanup,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

我想和你一起查阅一些代码。我有:

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/elif。通常,我会进入map-function dispatcher,但在每次if/elif之后,我都会有两行具有相同字典引用的代码。你能给我推荐一些干净的解决方案来替换那些难看的建筑吗


创建27个类来应用多态性或27个函数听起来不太好。。。你觉得怎么样?

你说得对,映射是一条路要走。用于从名称访问方法:

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)

您可以将元信息包含到您的枚举中,如果这对您的客户机代码来说是正确的,这意味着您拥有枚举。以下是一个例子:

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)

也许你可以用dict或tuple来表示这个操作,比如

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

然后你可以像这样访问它

obj = globals()[op['target']+'Dictionary']()
getattr(obj, op['action'])(*op['params'])

使用哈希表(一个以方法为值的字典)谢谢回复。但是我需要创建27个函数。有更好的解决方案吗?您可以使用lambdas和由
分隔的语句某些参数在所有情况下都有所不同,那么code>?如果复杂性是必要的,那么唯一的问题就是你希望复杂性出现在哪里。是的,你可以把它移动到一个dict或模块或其他任何东西中,但它仍然在那里。如果复杂性不是必需的,那么有一种模式允许您简化复杂性,但使用简化可能会带来成本,例如在将来灵活性会降低。调用我假定的函数-
self.klass=value[2]
operation.klass
Enum
属性(已经更新了答案),它表示要为每个操作类型初始化的类实例。使用
globals
是不礼貌的