Python:我的except子句确实太宽泛了吗?

时间:2016-12-28 07:53:00

标签: python html beautifulsoup pycharm try-except

我的代码工作正常,但PyCharm警告以下except条款过于宽泛。老实说,它也让我觉得这是错误的实施。

在批量抓取HTML <tr>时,我还必须添加到数据库或更新,我事先不知道游戏是否完成。此外,尚未完成的游戏在某些<td>中有不同的HTML标记,需要不同的处理。

基本上,如果我们查看match_score_stringmatch_relevant_bit,我们会告诉BeautifulSoup查找具有特定类别的<td>。如果游戏已经完成,则此<td>将有一个score-time sc课程,如果没有,则会有一个score-time st课程。如果它有一个,它就不会拥有另一个。

自从我编写try-except条款以来已经有一段时间了,但如果我没记错的话,原因(我觉得)我必须使用它们是因为BS会抛出错误并停止所有操作当row.find无法找到HTML对象时。

PyCharm是否有理由抱怨?

# Get Match Score
try:
    match_score_string = row.find("td", class_="score-time sc").get_text()
    match_string_split = match_score_string.split(" - ")
    team_a_score = int(match_string_split[0])
    team_b_score = int(match_string_split[1])
    print(team_a_score)
    print(team_b_score)
except:
    team_a_score = None
    team_b_score = None

# Get Match URL
try:
   match_relevant_bit = row.find("td", class_="score-time sc")
   match_url = match_relevant_bit.find("a").get("href")
   match_url_done = match_url.rsplit('?JKLMN')
   match_url = match_url_done[0]
   match_finished = True

except:

   match_relevant_bit = row.find("td", class_="score-time st")
   match_url = match_relevant_bit.find("a").get("href")
   match_url_done = match_url.rsplit('?JKLMN')
   match_url = match_url_done[0]
   match_finished = False

2 个答案:

答案 0 :(得分:3)

您的except肯定过于宽泛。在这些情况下,我不确定是否需要异常处理,我不会提出异议 - 例外是相当pythonic所以在你觉得合适的地方使用它们。但是,您还没有争辩说您需要使用代码来处理可以想象的每个异常。裸露的除外可以掩盖各种各样的错误。例如如果您在以后的版本中拼错变量名称:

try:
    match_score_string = row.find("td", class_="score-time sc").get_text()
    match_string_split = match_score_string.split(" - ")
    team_a_score = int(match_string_spilt[0])  # oops
    team_b_score = int(match_string_split[1])
    print(team_a_score)
    print(team_b_score)
except:
    team_a_score = None
    team_b_score = None

裸露的例外也会阻止用户发送KeyboardInterrupt来终止该程序......

这只是两个例子,为什么你不想要一个裸露的 - 除了可以被这掩盖的编程错误的数量接近无限,我没有足够的时间来证明所有的他们; - )。

相反,您应该准确指定您希望遇到的异常:

try:
    match_score_string = row.find("td", class_="score-time sc").get_text()
    match_string_split = match_score_string.split(" - ")
    team_a_score = int(match_string_spilt[0])  # oops
    team_b_score = int(match_string_split[1])
    print(team_a_score)
    print(team_b_score)
except AttributeError:  # If no row is found, accessing get_text fails.
    team_a_score = None
    team_b_score = None

这样,代码就像你期望的那样执行你不会掩盖(太多)编程错误。为防止隐藏错误,您要做的下一步是尽可能地限制异常处理程序中的代码量。

答案 1 :(得分:0)

尝试/除外条款很棒。听起来你不经常使用它们。

try/except块可以帮助您避免复杂的if语句,或者在继续之前检查条件的代码,这有时会使您不清楚自己尝试要做什么(请参阅我的内容)在那里:P)。

有一些例外情况可能会拖出您的代码,其中一些可能比其他代码更有可能。见下文:

try:
    # This first line could have an AttributeError in two places
    #     Maybe the row didn't parse quite correctly? find() won't work then.
    #     Maybe you didn't find any elements? get_text() won't work then.
    match_score_string = row.find("td", class_="score-time sc").get_text()
                            ^                                  ^
    # Same as here, you could get an AttributeError if match_score_string isn't a string.
    #     I would say that isn't very likely in this case,
    #     Especially if you handle the above line safely.
    match_string_split = match_score_string.split(" - ")

    # If either of these split strings contains no matches, you'll get an IndexError
    # If either of the strings at the index contain letters, you may get a ValueError
    team_a_score = int(match_string_split[0])
    team_b_score = int(match_string_split[1])

    # Theoretically, if you caught the exception from the above two lines
    #     you might get a NameError here, if the variables above never ended up being defined.
    print(team_a_score)
    print(team_b_score)
except:
    # Can't really imagine much going wrong here though.
    team_a_score = None
    team_b_score = None

正如您可能想象的那样,捕获几种类型的异常可能更有用。这取决于您输入的复杂程度。

多个try / except块在这里也是有益的,特别是为了处理你捕获错误并需要继续执行该块中其余代码的情况。