我想用Python编写一个函数,根据输入索引的值返回不同的固定值。

在其他语言中,我会使用switch或case语句,但Python似乎没有switch语句。在此场景中,推荐的Python解决方案是什么?


当前回答

我倾向于使用字典的解决方案是:

def decision_time( key, *args, **kwargs):
    def action1()
        """This function is a closure - and has access to all the arguments"""
        pass
    def action2()
        """This function is a closure - and has access to all the arguments"""
        pass
    def action3()
        """This function is a closure - and has access to all the arguments"""
        pass

   return {1:action1, 2:action2, 3:action3}.get(key,default)()

这样做的优点是它不需要每次都对函数求值,您只需确保外部函数获得内部函数所需的所有信息。

其他回答

如果您真的只是返回一个预定的固定值,那么可以创建一个字典,其中包含所有可能的输入索引作为键,以及它们的对应值。此外,您可能真的不希望函数执行此操作,除非您以某种方式计算返回值。

哦,如果你想做一些类似开关的事情,请看这里。

我一直喜欢这样做

result = {
  'a': lambda x: x * 5,
  'b': lambda x: x + 7,
  'c': lambda x: x - 2
}[value](x)

从这里开始

如果您不担心丢失案例套件中的语法高亮显示,可以执行以下操作:

exec {
    1: """
print ('one')
""", 
    2: """
print ('two')
""", 
    3: """
print ('three')
""",
}.get(value, """
print ('None')
""")

其中value是值。在C中,这将是:

switch (value) {
    case 1:
        printf("one");
        break;
    case 2:
        printf("two");
        break;
    case 3:
        printf("three");
        break;
    default:
        printf("None");
        break;
}

我们还可以创建一个helper函数来实现这一点:

def switch(value, cases, default):
    exec cases.get(value, default)

因此,我们可以将其用于一、二和三的示例:

switch(value, {
    1: """
print ('one')
    """, 
    2: """
print ('two')
    """, 
    3: """
print ('three')
    """,
}, """
print ('None')
""")

我认为最好的方法是使用Python语言的习惯用法来保持代码的可测试性。如前面的回答所示,我使用字典来利用python结构和语言,并以不同的方法隔离“case”代码。下面是一个类,但您可以直接使用模块、全局变量和函数。该类具有可以隔离测试的方法。

根据您的需要,您也可以使用静态方法和属性。

class ChoiceManager:

    def __init__(self):
        self.__choice_table = \
        {
            "CHOICE1" : self.my_func1,
            "CHOICE2" : self.my_func2,
        }

    def my_func1(self, data):
        pass

    def my_func2(self, data):
        pass

    def process(self, case, data):
        return self.__choice_table[case](data)

ChoiceManager().process("CHOICE1", my_data)

也可以使用类作为“__choice_table”的键来利用此方法。通过这种方式,您可以避免信息滥用,并保持所有信息的清洁和可测试性。

假设您必须处理来自网络或MQ的大量消息或数据包。每个数据包都有自己的结构和管理代码(以通用方式)。

使用以上代码,可以执行以下操作:

class PacketManager:

    def __init__(self):
        self.__choice_table = \
        {
            ControlMessage : self.my_func1,
            DiagnosticMessage : self.my_func2,
        }

    def my_func1(self, data):
        # process the control message here
        pass

    def my_func2(self, data):
        # process the diagnostic message here
        pass

    def process(self, pkt):
        return self.__choice_table[pkt.__class__](pkt)

pkt = GetMyPacketFromNet()
PacketManager().process(pkt)


# isolated test or isolated usage example
def test_control_packet():
    p = ControlMessage()
    PacketManager().my_func1(p)

因此,复杂性不会在代码流中扩散,而是在代码结构中呈现。

易于记忆:

while True:
    try:
        x = int(input("Enter a numerical input: "))
    except:
        print("Invalid input - please enter a Integer!");
    if x==1:
        print("good");
    elif x==2:
        print("bad");
    elif x==3:
        break
    else:
        print ("terrible");