【问题标题】:Greedy execution of statements?贪婪地执行语句?
【发布时间】:2010-11-06 19:51:48
【问题描述】:

我用 BeautifulSoup 做了类似的事情:

for line in lines:
    code = l.find('span', {'class':'boldHeader'}).text
    coded = l.find('div', {'class':'Description'}).text
    definition = l.find('ul', {'class':'definitions'}).text
    print code, coded, def

但是,并非所有元素都始终存在。我可以将它包含在尝试中,除非它不会像这样破坏程序执行:

for line in lines:
    try:
      code = l.find('span', {'class':'boldHeader'}).text
      coded = l.find('div', {'class':'Description'}).text
      definition = l.find('ul', {'class':'definitions'}).text
      print code, coded, def
    except:
      pass

但是我如何以贪婪的方式执行语句?例如,如果只有两个可用的元素codecoded,我只想得到它们并继续执行。到目前为止,即使codecoded 存在,如果def 不存在,打印命令也永远不会执行。

这样做的一种方法是为每个这样的语句添加try...except

for line in lines:
    try:
      code = l.find('span', {'class':'boldHeader'}).text
    except:
      pass
    try:
      coded = l.find('div', {'class':'Description'}).text
    except:
      pass
    try:
      definition = l.find('ul', {'class':'definitions'}).text
    except:
      pass
    print code, coded, def

但这是一种丑陋的方法,我想要一些更清洁的方法。有什么建议吗?

【问题讨论】:

    标签: python beautifulsoup


    【解决方案1】:

    如何在函数中捕获“丑陋”的代码,并根据需要调用该函数:

    def get_txt(l,tag,classname):
        try:
            txt=l.find(tag, {'class':classname}).text
        except AttributeError:
            txt=None
        return txt
    
    for line in lines:
        code = get_txt(l,'span','boldHeader')
        coded = get_txt(l,'div','Description')
        defn = get_txt(l,'ul','definitions')
        print code, coded, defn
    

    PS。我将def 更改为defn,因为def 是Python 关键字。将其用作变量名会引发 SyntaxError。

    PPS。使用裸异常不是一个好习惯:

    try:
        ....
    except:
        ...
    

    因为它几乎总是能捕捉到更多你想要的东西。最好明确说明您要捕获的内容:

    try:
        ...
    except AttributeError as err:
        ...
    

    【讨论】:

    • 感谢您的建议。 +1 详细说明。经验教训:)
    • 不错的答案。将 try/catch 用作“正常”程序流程的一部分可能并不理想。
    【解决方案2】:

    首先,您可以测试 None 而不是捕获异常。 l.find 应该返回 None 如果它没有找到您的项目。应该为错误和非常特殊的情况保留异常。

    您可以做的第二件事是创建一个包含您要检查的所有 HTML 元素的数组,然后有一个嵌套的 for 循环。自从我使用 python 已经有一段时间了,我将概述代码,然后(希望)在测试时编辑答案。

    类似:

    elementsToCheck = [
                      [ 'span', {'class':'boldHeader'} ],
                      [ 'div', {'class':'Description'} ],
                      [ 'ul', {'class':'definitions'} ]]
    
    concatenated = ''
    for line in lines:
        for something in elementsToCheck
           element = l.find(something[0], something[1])
           if element is not None
              concatenated += element.text
    print concatenated
    

    显然上面的代码不起作用,但你应该明白了。 :)

    【讨论】:

    • 谢谢,我现在正在调查。但一个问题是find 实际上会引发异常,这是我开始使用try...catch 块的主要原因。那么在新的方法中,如果find抛出异常,会不会从for loop出来?
    • 或者我会在 for 循环中放一个 try...catch。我会回来的。为您的时间 +1。谢谢
    • @Legend:哦,如果它抛出,那么你需要抓住它。尽管如此,我还是会检查它是否实际上并没有引发空引用异常,因为您在一个空对象上调用.text(这似乎更合乎逻辑,但同样,我不太使用 python 来了解它的最佳实践)。
    • 所以我也检查了这种方法。它工作得很好:) @Paul McGuire:我不知道有人注意到这么小的事情。我想这是我在这里获得的知识所能做的至少:)
    猜你喜欢
    • 2018-05-13
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 2014-08-21
    相关资源
    最近更新 更多