equivalente “Python” para lidar com interruptor e comparação de seqüência múltipla

StackOverflow https://stackoverflow.com/questions/641469

  •  22-07-2019
  •  | 
  •  

Pergunta

Tudo bem, então meu título sugado. Um exemplo funciona melhor:

input = 'check yahoo.com'

Eu quero analisar de entrada, usando a primeira palavra como o "comando", eo resto da cadeia como um parâmetro. Aqui está a versão simples de como minha mente não Pythonic é codificação-lo:

if len(input) > 0:
    a = input.split(' ')
    if a[0] == 'check':
        if len(a) > 1:
            do_check(a[1])
    elif a[0] == 'search':
        if len(a) > 1:
            do_search(a[1])

Eu gosto de Python porque faz normalmente complicado as coisas em coisas bastante simples. Eu não estou muito experiente com ele, e eu estou bastante certo de que há uma maneira melhor coisa para fazer essas coisas ... alguma maneira mais Python. Eu vi alguns exemplos de pessoas que substituem declarações switch com dicts e funções lambda, enquanto outras pessoas simplesmente recomendado if..else ninhos.

Foi útil?

Solução

dispatch = {
  'check': do_check,
  'search': do_search,
}
cmd, _, arg = input.partition(' ')
if cmd in dispatch:
    dispatch[cmd](arg)
else:
    do_default(cmd, arg)

Outras dicas

Estou bastante certeza de que há uma maneira melhor coisa para fazer essas coisas ... alguma maneira mais Python.

Não é verdade. Você código é simples, clara, óbvia e Inglês-like.

Eu vi alguns exemplos de pessoas que substituem declarações switch com dicts e funções lambda,

Sim, você já viu-los e eles não são claras, óbvias ou Inglês-like. Eles existem porque algumas pessoas gostam de torcer as mãos sobre a instrução switch.

enquanto outras pessoas simplesmente recomendado if..else ninhos.

Correto. Eles trabalham. Eles são simples, clara, ...

Seu código é bom. Deixá-lo sozinho. Seguir em frente.

Isto permite-lhe evitar dar o nome de cada comando duas vezes; nomes de função são usados ??quase directamente, como nomes de comando.

class CommandFunctions:
    def c_check(self, arg):
        print "checking", arg

    def c_search(self, arg):
        print "searching for", arg

    def c_compare(self, arg1, arg2):
        print "comparing", arg1, "with", arg2

    def execute(self, line):
        words = line.split(' ')
        fn = getattr(self, 'c_' + words[0], None)
        if fn is None:
            import sys
            sys.stderr.write('error: no such command "%s"\n' % words[0])
            return
        fn(*words[1:])

cf = CommandFunctions()
import sys
for line in sys.stdin:
    cf.execute(line.strip())

Se você está procurando uma abordagem one liner 'pythônico' para isso você pode usar isto:


def do_check(x): print 'checking for:', x
def do_search(x): print 'searching for:', x

input = 'check yahoo.com'
{'check': do_check}.get(input.split()[0], do_search)(input.split()[1])
# checking for: yahoo.com

input = 'search google.com'
{'check': do_check}.get(input.split()[0], do_search)(input.split()[1])
# searching for: google.com

input = 'foo bar.com'
{'check': do_check}.get(input.split()[0], do_search)(input.split()[1])
# searching for: bar.com

O desrespeito, eu só percebi que a minha resposta foi semelhante a uma das outras respostas - e, aparentemente, não há nenhuma tecla delete:)

Variação na resposta de @ MizardX :

from collections import defaultdict

dispatch = defaultdict(do_default, check=do_check, search=do_search)
cmd, _, arg = input.partition(' ')
dispatch[cmd](arg)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top