我有一些话题需要讨论。我有一个包含24 if
s / elif
s的代码片段。 Operation
是我自己的类,表示与Enum
类似的功能。
这是一段代码:
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个类并使用polymorphism?我不相信它会使我的代码可维护......从一方面来看,if
非常清楚,并且不应该难以理解,另一方面,if
太多了StartObject()
第
我的问题相当普遍,但是我用Python编写代码,所以我不能使用像switch
这样的结构。
您怎么看?
更新:
一件重要的事情是StopObject()
,StatusObject()
和strategy
是构造函数,我想将对象分配给div { font-size:2vw}
引用。
答案 0 :(得分:12)
您可以使用字典。字典存储引用,这意味着函数完全可以使用,如下所示:
operationFuncs = {
Operation.START: strategy_objects.StartObject
Operation.STOP: strategy_objects.StopObject
Operation.STATUS: strategy_objects.StatusObject
(...)
}
有一个默认操作以防万一,所以当你运行它时使用try except
并处理异常(即相当于你的else
子句)
try:
strategy = operationFuncs[operation]()
except KeyError:
strategy = strategy_objects.DefaultObject()
或者使用字典的get
方法,如果找不到您提供的密钥,则可以指定默认值。
strategy = operationFuncs.get(operation(), DefaultObject())
请注意,在将它们存储在字典中时,不要包含括号,只需在调用字典时使用它们。这也要求Operation.START
可以使用,但是应该是这种情况,因为您将其描述为类似于ENUM的类。
答案 1 :(得分:3)
Python等同于switch语句是使用字典。基本上,您可以像存储案例那样存储键,并且值将是针对该特定情况调用的值。因为函数是Python中的对象,所以可以将它们存储为字典值:
d[operation]()
然后可以按如下方式使用:
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
这可能会比乱七八糟的if-else语句更好地扩展。请注意,如果您没有其他案件可以处理,则可以直接使用strategy = operation_dispatcher.get(operation, default)
strategy() #call if needed
字典。
答案 2 :(得分:2)
您可以尝试类似this的内容。
例如:
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)而不使用该函数。
答案 3 :(得分:1)
您可以使用getattr
:
strategy = getattr(strategy_objects, "%sObject" % operation.capitalize())()
假设操作是“STATUS”,它将大写为“Status”,然后前置为“Object”,给出“StatusObject”。然后将在StatusObject
上调用strategy_objects
方法,如果此属性不存在,或者如果它不可调用,则会发生灾难性故障。 :)(即添加错误处理。)
字典解决方案可能更灵活。
答案 4 :(得分:0)
如果PDO
等是可以清除的,你可以使用带有键的字典作为条件,使用值作为要调用的函数,例如 -
Operation.START
然后您可以执行此字典查找并调用函数,示例 -
d = {Operation.START: strategy_objects.StartObject ,
Operation.STOP: strategy_objects.StopObject,
Operation.STATUS: strategy_objects.StatusObject}
答案 5 :(得分:-1)
这是一个使用词典完成的混蛋开关/案例:
例如:
# 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"]()