字典还是if语句,Jython

4 投票
5 回答
3318 浏览
提问于 2025-04-11 09:35

我现在正在写一个脚本,目的是从HTML中提取一些特定的信息,使用的是dom4j这个工具。

因为Python/Jython没有原生的switch语句,所以我决定用一堆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

你会如何对handle方法进行相应的修改来实现这个呢?希望你明白我的意思 :)

谢谢

5 个回答

1

你对字典的使用不太正确。在你的实现中,所有的方法都会被调用,而那些没用的方法会被丢弃。通常我们会这样做:

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

这样做会更快,而且如果你有很多(或者数量不固定的)项目时,也更容易扩展。

2

根据你的代码,你的所有函数都会被调用。

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

handlers[type](dom)

这就像你最开始的if代码一样工作。

14

为了避免在字典中指定标签和处理器,你可以直接使用一个处理器类,并给它的方法起个名字,让这些名字和类型相匹配。比如:

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)

更新:

当你有多个参数时,只需修改处理函数,让它接收这些参数,并把它们传递给其他函数。如果你想让这个处理器更通用(这样在改变参数时就不需要同时修改处理函数和处理方法),你可以使用 *args 和 **kwargs 这种语法来传递所有接收到的参数。这样,处理方法就变成:

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)

撰写回答