字典或If语句,Jython

时间:2008-11-10 14:20:14

标签: python switch-statement jython

我正在编写一个脚本,它将使用dom4j从HTML中获取某些信息。

由于Python / Jython没有原生开关语句,我决定使用一大堆 if 语句调用适当的方法,如下所示:

if type == 'extractTitle':
    extractTitle(dom)
if type == 'extractMetaTags':
    extractMetaTags(dom)

我将添加更多内容,具体取决于我想从HTML中提取哪些信息,并考虑采用我在本网站其他地方找到的字典方法,例如:

{
    'extractTitle':    extractTitle,
    'extractMetaTags': extractMetaTags
}[type](dom)

我知道每次运行脚本时都会构建字典,但同时如果我使用 if 语句,脚本必须检查所有脚本,直到它击中正确的一个。我真的想知道哪一个更好或者通常更好的做法?

更新: @Brian - 感谢您的回复。我有一个问题,如果任何提取方法需要多个对象,例如

handle_extractTag(self, dom, anotherObject)
# Do something

您如何对句柄方法进行适当的更改以实现此目的?希望你知道我的意思:)。

干杯

5 个答案:

答案 0 :(得分:14)

为了避免在dict中指定标记和处理程序,您可以使用一个处理程序类,其方法名称与该类型匹配。例如

class  MyHandler(object):
    def handle_extractTitle(self, dom):
        # do something

    def handle_extractMetaTags(self, dom):
        # do something

    def handle(self, type, dom):
        func = getattr(self, 'handle_%s' % type, None)
        if func is None:
            raise Exception("No handler for type %r" % type)
        return func(dom)

用法:

 handler = MyHandler()
 handler.handle('extractTitle', dom)

更新:

当你有多个参数时,只需更改handle函数以获取这些参数并将它们传递给函数。如果你想让它更通用(所以你不必在更改参数签名时更改处理函数和handle方法),你可以使用* args和** kwargs语法来传递所有收到的参数。然后handle方法变为:

def handle(self, type, *args, **kwargs):
    func = getattr(self, 'handle_%s' % type, None)
    if func is None:
        raise Exception("No handler for type %r" % type)
    return func(*args, **kwargs)

答案 1 :(得分:2)

使用您的代码运行您的所有函数都会被调用。

handlers = {
'extractTitle': extractTitle, 
'extractMetaTags': extractMetaTags
}

handlers[type](dom)

与您原来的if代码一样。

答案 2 :(得分:1)

这取决于我们谈论的if语句数量;如果它是一个非常小的数字,那么它将比使用字典更有效。

然而,与往常一样,我强烈建议您做任何事情,使您的代码看起来更干净,直到经验和分析告诉您需要优化特定的代码块。

答案 3 :(得分:1)

您对词典的使用并不完全正确。在您的实现中,将调用所有方法,并丢弃所有无用的方法。通常做的更像是:

switch_dict = {'extractTitle': extractTitle, 
               'extractMetaTags': extractMetaTags}
switch_dict[type](dom)

如果您有大量(或可变)的项目,那么这种方式会更加简洁和可扩展。

答案 4 :(得分:1)

效率问题几乎无关紧要。字典查找使用简单的散列技术完成,if语句必须一次评估一个。字典往往更快。

我建议你实际上有从DOM中提取的多态对象。

不清楚type是如何设置的,但它确实看起来可能是一系列相关对象,而不是简单的字符串。

class ExtractTitle( object ):
    def process( dom ):
        return something

class ExtractMetaTags( object ):
    def process( dom ):
        return something

不是设置type =“extractTitle”,而是执行此操作。

type= ExtractTitle() # or ExtractMetaTags() or ExtractWhatever()
type.process( dom )

然后,您将不会构建此特定字典或if语句。