8

好吧,所以我的标题很烂。一个例子效果更好:

input = 'check yahoo.com'

我想解析输入,使用第一个单词作为“命令”,并将字符串的其余部分作为参数。这是我的非 Pythonic 思维如何编码的简单版本:

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])

我喜欢 Python,因为它将通常复杂的事情变成了相当简单的事情。我对它不是太有经验,而且我相当确定有更好的方法来做这些事情......某种方式更pythonic。我见过一些人用 dicts 和 lambda 函数替换 switch 语句的例子,而其他人只是推荐 if..else 嵌套。

4

6 回答 6

31
dispatch = {
  'check': do_check,
  'search': do_search,
}
cmd, _, arg = input.partition(' ')
if cmd in dispatch:
    dispatch[cmd](arg)
else:
    do_default(cmd, arg)
于 2009-03-13T04:37:58.593 回答
4

我相当肯定有一种更好的方法来做这些事情......某种方式更pythonic。

并不真地。您的代码简单、清晰、明显且类似于英语。

我见过一些用 dicts 和 lambda 函数替换 switch 语句的例子,

是的,你已经看到了它们,但它们并不清晰、不明显或类似英语。它们的存在是因为有些人喜欢在 switch 语句上绞尽脑汁。

而其他人只是推荐 if..else 巢。

正确的。他们工作。它们简单、清晰、...

你的代码很好。不要管它。继续。

于 2009-03-13T10:08:02.293 回答
3

这可以让您避免给每个命令名称两次;函数名几乎直接用作命令名。

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())
于 2009-03-13T05:50:13.757 回答
0

如果您正在寻找一种单一的“pythonic”方法,您可以使用以下方法:


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
于 2009-03-13T05:11:16.470 回答
0

忽略,我只是意识到我的答案与其他答案之一相似-显然没有删除键:)

于 2009-03-16T02:06:21.110 回答
0

@MizardX 答案的变化:

from collections import defaultdict

dispatch = defaultdict(do_default, check=do_check, search=do_search)
cmd, _, arg = input.partition(' ')
dispatch[cmd](arg)
于 2009-06-13T17:05:03.163 回答