Python: 我的 except 子句真的太宽泛了吗?
Python: Is my except clause indeed too broad?
我的代码运行良好,但 PyCharm 警告以下 except
子句过于宽泛。老实说,它在我看来也是错误的实现。
当批量抓取 HTML<tr>
s 时,我还必须将其添加到数据库或更新,我事先不知道游戏是否完成。此外,尚未完成的游戏在某些 <td>
中有不同的 HTML 标签,需要不同的处理方式。
基本上,如果我们查看 match_score_string
和 match_relevant_bit
,我们就是在告诉 BeautifulSoup 找到具有特定 class 的 <td>
。如果游戏已经结束,这个 <td>
会有一个 score-time sc
class,如果没有,它会有一个 score-time st
class。如果它有一个,它不会有另一个。
我写 try-except
子句已经有一段时间了,但如果我没记错的话,(我觉得)我必须使用它们的原因是因为当 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
您的 except
确实太宽泛了。我不会质疑在这些情况下您是否需要异常处理——异常是非常 pythonic 的,所以在您认为合适的地方使用它们。但是,您没有争辩说您需要您的代码来处理 每个 可以想象的异常。一个 bare except 可以掩盖各种错误。例如如果您在以后的修订版中拼错了变量名:
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
Bare excepts 还会阻止用户发送 KeyboardInterrupt
来终止程序...
这只是两个例子,为什么你不想要一个简单的 except -- 由于可能被它掩盖的编程错误的数量几乎是无限的,我没有足够的时间来演示所有这些错误; -).
相反,您应该准确指定您预计会遇到的异常情况:
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
这样,代码会按您预期的方式执行并且您不会掩盖(太多)编程错误。为了防止隐藏错误,您接下来要做的是尽可能限制异常处理程序中的代码量。
Try/except 条款很棒。听起来你不太经常使用它们。
try/except
块可以帮助您避免复杂的 if 语句,或者在继续之前检查条件的代码,这有时会使您不清楚 trying to做(看看我在那里做了什么 :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 块在这里也有好处,特别是处理您发现错误并需要继续执行该块内其余代码的情况。
我的代码运行良好,但 PyCharm 警告以下 except
子句过于宽泛。老实说,它在我看来也是错误的实现。
当批量抓取 HTML<tr>
s 时,我还必须将其添加到数据库或更新,我事先不知道游戏是否完成。此外,尚未完成的游戏在某些 <td>
中有不同的 HTML 标签,需要不同的处理方式。
基本上,如果我们查看 match_score_string
和 match_relevant_bit
,我们就是在告诉 BeautifulSoup 找到具有特定 class 的 <td>
。如果游戏已经结束,这个 <td>
会有一个 score-time sc
class,如果没有,它会有一个 score-time st
class。如果它有一个,它不会有另一个。
我写 try-except
子句已经有一段时间了,但如果我没记错的话,(我觉得)我必须使用它们的原因是因为当 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
您的 except
确实太宽泛了。我不会质疑在这些情况下您是否需要异常处理——异常是非常 pythonic 的,所以在您认为合适的地方使用它们。但是,您没有争辩说您需要您的代码来处理 每个 可以想象的异常。一个 bare except 可以掩盖各种错误。例如如果您在以后的修订版中拼错了变量名:
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
Bare excepts 还会阻止用户发送 KeyboardInterrupt
来终止程序...
这只是两个例子,为什么你不想要一个简单的 except -- 由于可能被它掩盖的编程错误的数量几乎是无限的,我没有足够的时间来演示所有这些错误; -).
相反,您应该准确指定您预计会遇到的异常情况:
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
这样,代码会按您预期的方式执行并且您不会掩盖(太多)编程错误。为了防止隐藏错误,您接下来要做的是尽可能限制异常处理程序中的代码量。
Try/except 条款很棒。听起来你不太经常使用它们。
try/except
块可以帮助您避免复杂的 if 语句,或者在继续之前检查条件的代码,这有时会使您不清楚 trying to做(看看我在那里做了什么 :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 块在这里也有好处,特别是处理您发现错误并需要继续执行该块内其余代码的情况。