使用Try/except检查字符串

3

我对如何使用Try/Exceptionif/else感到困惑。如果我想告诉用户提供.html文件,我该如何编写惯用代码?

if url[-4:] ==".html":
        // do your things
else: 
    print('Error! the file is not html file')

我正在检查在这种情况下是否应该使用 try/exception 还是像我做的那样使用 if/else


嗯...在Python中,异常处理是非常便宜的,并且可以用作消息传递机制。因此,您可以引发MyInputException('Error! the file is not html file')来触发处理输入错误的代码,而不是“打印”错误信息。 - Paulo Scardine
你有一个问题:url[-4:]是"html"而不是".html",所以if语句将始终失败。此外,用户可能会使用".htm"类型的文件名和/或他们可能会使用大写字母。如果文件名少于5个字符怎么办? - Marichyasana
4个回答

4
在Python中,"宁愿求得原谅,也不要事先征得许可"( Easier to ask for forgiveness than permission)是惯用的方式。换句话说,在Python中,应该让异常被抛出并根据情况作出反应,而不是显式地检查条件("先看再跳",也在链接的术语表中提到)。因此,你的代码应该像这样:
try:
    # do your thing with `url`
except:
    print('Error! the file is not html file')

但是我该如何指定条件,如果url[-4:]==“.html”? - user3378649
@user3378649 当然可以,但关键是:一般情况下你不应该这样做。继续进行正常操作,如果文件最终不是HTML格式,错误处理代码会自动启动。 - Óscar López
1
@user3378649 不,如果你真的想让输入以“.html”结尾,那么使用try/except而不是使用if来测试它是没有惯用方法的。 - Paulo Scardine
1
你可以遵循try except原则,并使用assert语句进行if检查。当if失败时,它会抛出一个错误,而你的except将捕获它。 - kartikg3
我不会说EAFP总是适用的;你可以使用LBYL或EAFP,但与大多数命令式语言相比,Python中的EAFP往往更便宜。请谨慎使用两者。在Python中,将EAFP用于鸭子类型确实是惯用法,而使用'isinstance'测试的LBYL则不受欢迎。 - Paulo Scardine

4
简而言之:
try:
    a = q.get()

try 的意思是尝试这个东西,如果它有效,就使用它,否则except 如果它失败或者出现ValueError等错误,就使用其他东西。

except:
    a = None

更新时间:

try:
   url[-4:] == ".html"

except: 
    print "Error"

1
这个答案事实上是错误的。如果语句为假,try: url[-4:] == ".html" 不会抛出任何异常。 - dom0
在回顾中,@dom0,是的和不是的,except 中的 url 没有被重新赋值。但是,在之前的例子中,我已经解释了如何正确使用 tryexcept,我认为 user3378649 正在寻找这个答案。 - Jonathan Davies
警告:不要过度使用EAFP - 特别是如果LBYL相对较便宜 - 如果廉价的测试可以起作用,为什么要尝试昂贵的操作? - Paulo Scardine

2
如果你想让文件名以".html"结尾,使用if语句来测试是完全可以的。
如果你希望将异常上抛到几个代码级别以上进行捕获,也可以使用assert语句:
assert url.lower().endswith(".html"), u"the file name must end in .html"

这只是一种语法糖,其实质是:
if url.lower().endswith(".html"):
    do_your_things_with_url(url)
else: 
    raise YourCustomException('the url must end in ".html"')

当然,用以下语句替换简单的if测试是很愚蠢的:
try:
    assert url.lower().endswith(".html")
except AssertionError:
    print('Error! url does not end in ".html"')
else:
    do_your_things_with_url(url)

因此回答你的问题,你可能应该使用if测试来测试字符串是否以".html"结尾。
PS:这种风格称为LBYL(先看后跳),在Python中没有任何问题。另一种选择是EAFP(宁愿请求原谅,也不要事先获得许可)。两种方式都可以,并且在大多数情况下被认为是惯用的,但有一些例外情况(例如鸭子类型,在这种情况下,明显更喜欢使用EAFP样式而不是使用hasattr和/或isinstance进行LBYL测试)。不要过度使用EAFP,特别是如果LBYL相对较便宜-如果廉价的测试可以起作用,为什么要尝试昂贵的操作呢?

0
与其检查文件扩展名,不如尝试将文件解析为HTML,如果出现HTML解析异常,则向用户显示有用的错误信息。例如,使用BeautifulSoupHTMLParser
from bs4 import BeautifulSoup
from html.parser import HTMLParseError

try:
    BeautifulSoup(fetched_url_contents)
except HTMLParseError:
    print("Error: you haven't given me html!")

感谢将这个问题置顶。这是一个与Try/except使用相关的问题,我正在使用它来验证HTML文件。 - user3378649

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接