Python 太多的if语句

Python 太多的if语句,python,if-statement,conditional,code-readability,code-maintainability,Python,If Statement,Conditional,Code Readability,Code Maintainability,我有一些话题要讨论。我有一段24ifs/elifs的代码操作是我自己的类,表示类似于的功能下面是一段代码: if operation == Operation.START: strategy = strategy_objects.StartObject() elif operation == Operation.STOP: strategy = strategy_objects.StopObject() elif operation == Operation.STATUS:

我有一些话题要讨论。我有一段24
if
s/
elif
s的代码<代码>操作是我自己的类,表示类似于的功能
下面是一段代码:

if operation == Operation.START:
    strategy = strategy_objects.StartObject()
elif operation == Operation.STOP:
    strategy = strategy_objects.StopObject()
elif operation == Operation.STATUS:
    strategy = strategy_objects.StatusObject()
(...)
我从可读性的角度考虑问题。最好将其改为24类并使用?我不相信它会使我的代码可维护。。。一方面,那些
if
s非常清晰,应该不难理解,另一方面,如果
if
s太多了

我的问题相当笼统,但是我正在用Python编写代码,所以我不能使用这样的结构

你觉得怎么样


更新


一件重要的事情是
StartObject()
StopObject()
StatusObject()
都是构造函数,我想给
策略
引用分配一个对象。

你可以使用字典。字典存储引用,这意味着函数完全可以使用,如下所示:

operationFuncs = {
    Operation.START: strategy_objects.StartObject
    Operation.STOP: strategy_objects.StopObject
    Operation.STATUS: strategy_objects.StatusObject
    (...)                  
}
最好有一个默认操作以防万一,因此当您运行它时,请使用
try except
并处理异常(即相当于
else
子句)

或者使用字典的
get
方法,如果找不到提供的键,则可以指定默认值

strategy = operationFuncs.get(operation(), DefaultObject())

请注意,在字典中存储括号时不包括括号,只在调用字典时使用括号。这也要求
Operation.START
是可散列的,但情况应该是这样的,因为您将其描述为类似于枚举的类。

如果
Operation.START
等是可散列的,您可以使用字典,其中键作为条件,值作为要调用的函数,例如-

d = {Operation.START: strategy_objects.StartObject , 
     Operation.STOP: strategy_objects.StopObject, 
     Operation.STATUS: strategy_objects.StatusObject}
然后,您可以进行字典查找并调用函数,例如-

d[operation]()

Python的switch语句的等价物是使用字典。基本上,您可以像存储案例一样存储键,并且这些值就是针对特定案例所调用的值。因为函数是Python中的对象,所以可以将它们存储为字典值:

operation_dispatcher = {
    Operation.START: strategy_objects.StartObject,
    Operation.STOP: strategy_objects.StopObject,
}
然后可按如下方式使用:

try:
    strategy = operation_dispatcher[operation] #fetch the strategy
except KeyError:
    strategy = default #this deals with the else-case (if you have one)
strategy() #call if needed
或者更简洁地说:

strategy = operation_dispatcher.get(operation, default)
strategy() #call if needed

这可能比使用一堆if-else语句更好。请注意,如果您没有else案例需要处理,您可以直接使用字典与
operation\u dispatcher[operation]

以下是使用字典完成的bastardized开关/案例:

例如:

# define the function blocks
def start():
    strategy = strategy_objects.StartObject()

def stop():
    strategy = strategy_objects.StopObject()

def status():
    strategy = strategy_objects.StatusObject()

# map the inputs to the function blocks
options = {"start" : start,
           "stop" : stop,
           "status" : status,

}
然后调用等效开关块:

options["string"]()

您可以对
getattr
使用一些内省:

 strategy = getattr(strategy_objects, "%sObject" % operation.capitalize())()
假设操作是“STATUS”,它将大写为“STATUS”,然后在“Object”前面加上“StatusObject”。然后将对
策略\u对象调用
状态对象
方法,如果此属性不存在或不可调用,则会发生灾难性失败。:)(即添加错误处理。)


不过,字典解决方案可能更灵活。

您可以尝试以下方法

例如:

def chooseStrategy(op):
    return {
        Operation.START: strategy_objects.StartObject
        Operation.STOP: strategy_objects.StopObject
    }.get(op, strategy_objects.DefaultValue)
这样说吧

strategy = chooseStrategy(operation)()

此方法的优点是提供默认值(如最终else语句)。当然,如果您只需要在代码中的一个位置使用此决策逻辑,则始终可以使用strategy=dictionary.get(op,default),而不使用该函数。

case
语句?或者有一个方法引用数组来动态调用,例如,无论python的
array\u of_methods[operation]()
等价物是什么,python都没有switch/case语句。但是
strategy
对于每个小函数都是本地的,并且在执行
options[“string”]()
的范围内不可见。您错过了调用<代码>策略=选择策略(操作)(
谢谢!我没注意到他在说选择的策略。我已经编辑了我的帖子。使用hasattr(…)检查类是否存在将相当于字典解决方案中的KeyError。
strategy = chooseStrategy(operation)()