如何忽略Python中的所有潜在异常?

How to ignore all potential exceptions in Python?

我正在用python编写一个自定义备份脚本。有时mkdir函数或print函数或任何函数由于各种原因而失败。这样的异常会停止整个脚本,并在中间停止备份,这非常令人沮丧。到目前为止,我已经通过添加try来解决这些问题:…除了…声明并正确管理这些异常。然而,有一天,由于其他一些尚未触发的原因,其他一些语句或函数也可能引发异常。

是否有方法告诉脚本继续?相当于在try中包装代码的每个语句:…例外:通过条款?当然,一根圆木会更好。

我注意到,在使用类似tkinter的GUI工具包编程时,即使出现异常,应用程序也会继续运行。有没有可能用控制台完成这类工作?


实际上有一个模块应该这样做:https://github.com/ajalt/fuckitpy。

尽管它显然是作为一个笑话写的。我无法想象这样的情况是个好主意。天哪,我简直不敢相信我竟然建议这么做。

您应该做的是识别哪些代码行可以产生什么类型的错误,并正确地处理这些错误。只有如此多的地方会发生错误——主要是在与外部系统(包括文件系统、网络、用户输入等)进行接口时,记住,实际失败往往比继续"工作"和混乱数据、文件等要好。例外是有原因的,它们不是guido恶意的结果。


python没有办法做到这一点,这是有充分理由的。

似乎你对写"健壮的"软件意味着什么感到困惑:一个健壮的程序不是一个很难杀死的程序,它将继续运行,无论什么,而是一个能够正确处理边缘情况的程序。继续跑是不够的…坚持做明智的事情是关键。

不幸的是,没有办法自动地做合理的事情,你必须根据具体情况来考虑如何处理错误。

注意,如果一个程序有很多catch,那么它很少是一个好程序。例外情况本应在许多地方提出,却几乎一无所获。

还要注意,每个catch都可能是错误的来源…例如:

1
2
3
4
try:
    print my_dict[foo()]
except KeyError:
    ...

无法区分KeyError是来访问my_dict中不存在的密钥,还是从foo()中转义而来。很少情况下,这两个案件的处理方式应该相同…

最好是写:

1
2
3
4
5
key = foo()
if key in my_dict:
    print my_dict[key]
else:
    ...

这样,只处理my_dict中缺少密钥的附带情况,相反,KeyError异常将停止程序(当您不确定程序正在做什么时停止程序是唯一合理的操作)。


python将"base exception"作为异常类的基类。您可以捕获并忽略基类异常,这将覆盖所有异常。

1
2
3
4
try
    ... your code here ...
except BaseException as exp:
    print"A General Exception Occurred"


1
2
3
4
try:
   # code segment
except:
   pass

pass关键字将忽略所有异常


除了@kanwar saad提议的块,您可以添加一个通用块。问题是,在引发异常之后,您是否可以继续使程序处于有效状态?

来自Python禅:

1
2
Errors should never pass silently.
Unless explicitly silenced.

在我看来,设法抓住所有的例外是最好的方法。如果无法明确捕获异常,则不应尝试解决它。您(和您的用户)应该知道到底出了什么问题,否则您的代码可能会成为调试的噩梦。

如果您担心丢失备份数据,可以这样做:

1
2
3
4
5
6
7
8
9
10
def save_unfinished_backup():
    # try to find a graceful exit without losing any data

try:
    # some code
except OSError:
    # handle oS Errors
except Exception:
    save_unfinished_backup()
    raise

这样既可以避免数据丢失,又可以避免调试时的错误。

希望这有帮助!

有趣的是:你也可以使用该死的模块。它可以消除所有错误,包括语法错误。但是,不要在生产代码中使用它。

这应该是完美的。它不会打印"foo",但您可以在没有碰撞的情况下到达print("bar")

1
2
3
4
5
6
import fuckit

with fuckit:
    prnt("foo")

print("bar")

通常情况下,这个应该捕捉到所有的:

1
2
3
4
try:
   ....
except:
   pass

唯一的问题是,您没有用这种语法获得异常对象,但在本例中没有要求这样做。