使用except表示“如果那不起作用”

2024-04-27 03:52:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我完全理解了不捕获所有异常的一般原则,例如(Why is "except: pass" a bad programming practice?)。然而,我发现自己编写这个序列是为了得到一个类似文件的对象的源:

    try:
        self.doc.source = source.geturl()
    except:
        try:
            self.doc.source = pathlib.Path(os.path.abspath(source.name)).as_uri()
        except:
            self.doc.source = None

很明显,通过一些探索,我可以以合理的信心找出哪些具体的错误。但是at在这个问题(Python: How can I know which exceptions might be thrown from a method call)中被解释了,你永远不能确定。你知道吗

所以有没有更好的方法来做我在这里做的事情,基本上就是说:试试这个,如果不起作用,试试这个,如果不起作用,就做这个。因为这都是关于设置一个单一的变量,并且有一个设置为“无”的回退,所以我并不清楚这种构造的危险在哪里。你知道吗


Tags: 文件对象selfsourcedocis序列pass
1条回答
网友
1楼 · 发布于 2024-04-27 03:52:47

也许把它放到一个专门的函数里更好?你知道吗

def func(source):
   try:
       return source.geturl()
   except Exception:
       try:
           return pathlib.Path(os.path.abspath(source.name)).as_uri()
       except Exception:
           pass

关于吞咽异常的注释

忽略任何类型的异常都不是最佳模式:最好知道什么调用可以引发什么类型的异常。你知道吗

即使except ...: pass是坏的,这已经是您在示例中所做的,这里很明显,如果失败,我们将尝试另一种方法。你知道吗

糟糕的编程实践是将错误处理建立在捕捉任何类型错误的能力之上。就其本身而言,except: passexcept: <lots_of_things_that_wont_raise_again>好。你知道吗

然而,你提到的帖子中的第一个答案说了一件非常明智的事情:pass语义上表示除了例外,你不会做任何事情,而且由于你不存储在变量中,这也表明你再也不能访问它了(你可以,但仍然……)。作为/u/Aprillion/,您至少需要记录这些错误,否则,您可能会吞下非常有用的调试信息,这可能会使您(或其他人)的生活在某个时候变得更加困难。你知道吗

例如,如果geturl中隐藏了一个bug,使得它在正常情况下引发异常,会发生什么?它可能会隐藏很长一段时间,因为这个异常会被吞没,并且永远不会显示在任何地方。祝调试器好运找到它!你知道吗

改进的方法

  • 用可能引发的异常替换except Exception
  • 在尝试之前检查它是否会失败,这样就不必捕获异常

此外,您可能希望使用记录器在某个位置保存/显示这些异常,至少在调试模式下是这样。你知道吗

Clearly with some spelunking I could figure out which specific errors to catch with a reasonable degree of confidence. But at is explained in this question (Python: How can I know which exceptions might be thrown from a method call) you can't ever be quite certain.

为什么这会改变一切?如果geturl返回特定的异常类型,则只能捕获这些异常类型,并希望其他意外错误出现在解释器中。你知道吗

givn方法的一个大问题是,如果geturl未定义,或者不可调用,或者接受更多参数,这个错误不会使解释器崩溃,即使这是一个明显的编程错误。这是因为except:except Exception:将捕获大量Python错误,如果是AttributeErrorNameErrorImportError甚至SyntaxError。你知道吗

最后,我真的认为您更愿意用您可以捕获的异常列表来替换Exception(并且至少将异常发送给记录器)。请注意,您可以这样写:

   try:
       return source.geturl()
   except (ExceptionA, ExceptionB, ExceptionC):
       pass

相关问题 更多 >