我正在编写一个脚本,它将使用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
您如何对句柄方法进行适当的更改以实现此目的?希望你知道我的意思:)。
干杯
答案 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语句。