【问题标题】:In python should I use try or If and why?在 python 中,我应该使用 try 还是 If,为什么?
【发布时间】:2015-08-07 11:32:20
【问题描述】:

首先,我知道 if 和 try 之间的区别,并且我非常清楚它们的目的是完全不同的——一个进行测试,另一个管理错误。但是,在这种特殊情况下,使用 if 或 try 更好吗?

#option1
def getListRank(self):
    for point in self.soup.findAll('td',class_="rank-cell"):
        p = (point.get_text().replace('\t','').replace('\n','')
                             .replace('\r','').replace(',',''))
        if 'T' in p:
            self.listRk.append(int(p.replace('T',''))
        else:
            self.listRk.append(int(p))
    return self.listRk 

我很想使用以下选项 2,因为我知道可以阻止将 p 转换为整数的唯一原因是存在那个“T”。因此,这样写是不寻常还是效率低下:

#option2
def getListRank(self):
    for point in self.soup.findAll('td',class_="rank-cell"):
        p = (point.get_text().replace('\t','').replace('\n','')
                             .replace('\r','').replace(',',''))
        try:
            self.listRk.append(int(p))
        except:
            self.listRk.append(int(p.replace('T',''))                
    return self.listRk

我问这些问题是因为我以前读过这个,所以我认为它是“pythonic”。但是,如果有一段解释/约定,我会更感兴趣。

提前致谢

【问题讨论】:

  • 如果使用异常处理程序,请不要使用 Pokemon 风格的处理方式;您不想全部抓住。只捕获特定的异常,这里是except ValueError:
  • 何必呢?如果'T' 不在p 中,则p.replace('T','')p 相同
  • @tobias_k 当然可以。这只是举个例子。可能不是最好的,尤其是当我之前使用了这么多替换时。还是谢谢。
  • 另外,请确保在 try 块中添加尽可能少的内容。因此try: p = int(p); except ValueError: p = int(p.replace('T',''); self.listRk.append(p) 会好很多。

标签: python if-statement try-catch convention


【解决方案1】:

也不要使用。按照@tobias_k 的建议,删除T 和其他字符;那么你知道int(p) 会成功。您也可以使用 re.sub 更轻松地完成此操作,将其简化到足以使用列表解析而不是 for 循环。

import re

to_replace = re.compile(r'\t|\n|\r|T|,')
def getListRank(self):
    points = self.soup.findAll('td', class_="rank-cell")

    self.listRk = [int(re.sub(to_replace, "", p.get_text())) for p in points]
    return self.listRk

您也可以使用str.translate 删除您的字符集。

self.listRk = [int(p.get_text().translate(None, "\r\n\tT,")) for p in points]

【讨论】:

  • 我可以谦虚地建议编译那个正则表达式吗? :)
  • 我不肯定,但我认为它在第一次调用 re.sub 后会被编译和缓存。不过,它不会受到伤害。不过,我偏爱使用str.translate
  • 啊。 re docs do 说“大多数非平凡的应用程序总是使用编译的形式”,但我从未将其解释为非平凡的 re 方法会自动为您编译非编译的正则表达式。有趣......原则上,我也喜欢str.translate,因为翻译表可以在没有分支的情况下完成它们的工作,而且我通常在 C 中使用这种方法,但在 Python 中我一直忘记它的存在。 :)
  • 我也忘了,所以我先用re.sub :)
  • 感谢翻译!这对我有很大帮助!
【解决方案2】:

至少在 CPython 的解释器中,异常确实不会花费太多,而且有时更便宜,特别是如果测试需要更多 Python 级别的代码,而异常会由 C 层函数隐式引发。

选择if 检查异常的原因通常是风格问题;为实际异常情况保存异常,而不是作为通用控制流机制。也就是说,Python 完全是关于 EAFP,因此它倾向于将异常用于不太特殊的目的。

拜托,看在上帝的份上,不要使用除积木之外的裸露。捕获您期望的异常,仅此而已,因为否则您将捕获不应该被捕获的东西,例如如果您将append 拼写为apend,则AttributeError 将被捕获。

当然,在您的特定情况下,您可以完全跳过测试。

self.listRk.append(int(p.replace('T',''))

不管T 是否在你的字符串中都有效。检查它是没有意义的,如果它在那里就删除它并转换为int

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
  • 2015-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多