字典还是if语句,Jython
我现在正在写一个脚本,目的是从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)