在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
是不礼貌的