-3
if a == arg:
    if arg not in a_list:
        do_something(arg)
elif b == arg:
    if arg not in b_list:
        do_something(arg)
else:
    do_something_else(arg)

提出一种惯用的方法来缩短和特别干燥上述语句 - 而不将其部分提取到单独的函数中。

编辑:有趣 ;-) 这不是家庭作业,也不是审查我的代码的请求,也许如果我将上面的框架重新定义如下,我的意图会变得更加清晰:

在 if 语句之上编写的 Python 方式是什么,这样它既是 DRY 又是该语言的惯用语?我觉得我遗漏了一些东西,也许可以利用 python 中的 and/or 运算符?不将它的任何部分提取到单独的函数的原因是,这个问题更多地是关于重构而不是关于惯用的 pythonian if-logic。

4

2 回答 2

2

这是一个简单的答案:

for i, i_list  in [(a, a_list), (b, b_list)]:
    if i == arg:
        if arg not in i_list:
            do_something(arg)
        break
else:
    do_something_else(arg)

aa_listb、 和组合b_list成元组,我们可以更容易地迭代它们。然后是迭代本身的简单问题,匹配条件并运行所需的功能..

Python 支持for....else语句。

如果 for 循环中没有返回或中断,则 else 语句将运行。

在这里,如果我们得到了我们想要的匹配,循环就会中断,我们就完成了。如果我们从不中断,那么我们将进入我们的 else 循环。在我看来,这是最Pythonic的方式来做到这一点。

编辑

为了使它更好,你应该a, b, a_list, b_list在某种字典里面,在哪里d[a] = a_list

然后你可以像这样迭代dict:

for k, v  in d.items():
    if k == arg:
        if arg not in v:
            do_something(arg)
        break
else:
    do_something_else(arg)

这几乎是一样的,但看起来更好,你可以事先整理好所有的a's 和's 和列表。b

于 2012-11-28T15:08:41.710 回答
1
def run_for_match(candidate, patterns, search_lists, handlers, default_handler):
    for pattern, search_list, handler in zip(patterns, search_lists, handlers):
        if match(pattern, candidate):
            if candidate not in search_list:
                handler(candidate)
            break
    else:
        default_handler(candidate)

run_for_match(string, [a, b], [a_list, b_list], [do_something, do_something], do_something_else)

尽管将其放入封装patterns, search_lists,handlers和的对象中,但default_handler意义重大。就像是:

class StringHandlerManager(object):

    def __init__(self, default_handler):
        self.handler_registry = []
        self.default_handler = default_handler

    def add_handler(self, pattern, search_list, handler):
        self.handler_registry.append((pattern, search_list, handler))

    def __call__(self, candidate):
        for pattern, search_list, handler in self.handler_registry:
            if match(pattern, candidate):
                if candidate not in search_list:
                    handler(candidate)
                break
        else:
            default_handler(candidate)

handle_string = StringHandlerManager(do_something_else)
handle_string.add_handler(a, a_list, do_something)
handle_string.add_handler(b, b_list, do_something)
handle_string(string)
于 2012-11-28T14:33:33.740 回答