equivalente “Python” para lidar com interruptor e comparação de seqüência múltipla
-
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.
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)