在python中,我应该使用try还是If以及为什么?

在python中,我应该使用try还是If以及为什么?,python,if-statement,try-catch,convention,Python,If Statement,Try Catch,Convention,首先,我知道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','')

首先,我知道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”。然而,如果有一个解释/惯例,我非常感兴趣


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

如果检查异常,选择
的原因通常是风格问题;将异常保存为实际异常情况,而不是作为一般控制流机制。这就是说,Python就是这样,所以它倾向于将异常用于不太特殊的目的

看在上帝的份上,请不要用裸块。捕获您期望的异常,而不是更多,因为否则您将捕获本不应捕获的内容,例如,如果您将
append
键入为
apend
,则将捕获
AttributeError

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

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

不管字符串中是否有
T
,它都可以工作。检查它是没有意义的,如果它在那里就把它去掉,然后转换成
int

也不要使用。按照@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]

如果使用异常处理程序,请不要使用Pokemon样式的处理;你不想把他们都抓住。只捕获特定的异常,这里是
除了ValueError:
。相关:为什么要麻烦呢?如果
'T'
不在
p
中,那么
p.replace('T','')
p
@tobias\k当然是一样。这只是举个例子。也许不是最好的,尤其是当我以前用了这么多替换品的时候。无论如何,谢谢。另外,请确保在
try
块中添加尽可能少的内容。因此
try:p=int(p);除了ValueError:p=int(p.replace('T','');self.listRk.append(p)
会更好。我可以谦虚地建议编译该正则表达式吗?:)我不是肯定的,但我认为它在第一次调用
re.sub
后会被编译和缓存。不过,这不会有什么害处。不过,我倾向于使用
str.translate
。确实有人说“大多数非平凡的应用程序总是使用编译过的形式”,但我从未解释过这意味着非平凡的
re
方法会自动为您编译非编译过的正则表达式。有趣的。。。原则上,我也喜欢
str.translate
,因为translate表可以在没有分支的情况下完成它们的工作,我通常在C语言中使用这种方法,但在Python中我总是忘记它的存在我也忘了,所以我先用了
re.sub
谢谢你的翻译!这对我有很大帮助!?这听起来绝对像蟒蛇的素描…;)。EAFP的链接确实重定向到Python的语法维基百科文章。我想我应该提供,以防那些该死的鱼类病理学家偷了重定向。:-)