重构 python 中的 if 语句
Refactoring if statements in python
我想和你一起咨询一段代码。我有:
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 - 函数调度程序,但在每个 if / elif 之后,我都有两行代码具有相同的 dictionary 引用。你能建议我一些干净的解决方案来替换那些丑陋的结构吗?
创建 27 个 类 用于应用多态性或 27 个函数听起来不太好...您怎么看?
你说得对,映射是正确的方法。使用 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)
您可以将元信息包含在您的枚举中,如果这对您的客户端代码来说没问题,这意味着您拥有这些枚举。这是一个例子:
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)
也许你可以用字典或元组来表示操作,luke
op = {'target': 'Servers', 'action': 'start', 'params': (arg1, arg2)}
然后你就可以访问它了
obj = globals()[op['target']+'Dictionary']()
getattr(obj, op['action'])(*op['params'])
我想和你一起咨询一段代码。我有:
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 - 函数调度程序,但在每个 if / elif 之后,我都有两行代码具有相同的 dictionary 引用。你能建议我一些干净的解决方案来替换那些丑陋的结构吗?
创建 27 个 类 用于应用多态性或 27 个函数听起来不太好...您怎么看?
你说得对,映射是正确的方法。使用 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)
您可以将元信息包含在您的枚举中,如果这对您的客户端代码来说没问题,这意味着您拥有这些枚举。这是一个例子:
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)
也许你可以用字典或元组来表示操作,luke
op = {'target': 'Servers', 'action': 'start', 'params': (arg1, arg2)}
然后你就可以访问它了
obj = globals()[op['target']+'Dictionary']()
getattr(obj, op['action'])(*op['params'])