什么时候应该在Python中使用try-except?

时间:2018-01-11 06:09:52

标签: python python-3.x error-handling exception-handling

当我需要来自用户的输入数据或尝试启动线程时,我通常使用try-except块。但是,当一个人肯定应该使用try-except块时,是否有一些经验法则?从技术上讲,没有什么能阻止你做一些“聪明”的事情:

try:
    print("Hello world")
except:
    print("Bye bye world")

每当我感觉可能出现以下错误之一时,我是否应该实现try-except块?

$ python -m pydoc builtins


BaseException
    Exception
        ArithmeticError
            FloatingPointError
            OverflowError
            ZeroDivisionError
        AssertionError
        AttributeError
        BufferError
        EOFError
        ImportError
            ModuleNotFoundError
        LookupError
            IndexError
            KeyError
        MemoryError
        NameError
            UnboundLocalError
        OSError
            BlockingIOError
            ChildProcessError
            ConnectionError
                BrokenPipeError
                ConnectionAbortedError
                ConnectionRefusedError
                ConnectionResetError
            FileExistsError
            FileNotFoundError
            InterruptedError
            IsADirectoryError
            NotADirectoryError
            PermissionError
            ProcessLookupError
            TimeoutError
        ReferenceError
        RuntimeError
            NotImplementedError
            RecursionError
        StopAsyncIteration
        StopIteration
        SyntaxError
            IndentationError
                TabError
        SystemError
        TypeError
        ValueError
            UnicodeError
                UnicodeDecodeError
                UnicodeEncodeError
                UnicodeTranslateError
        Warning
            BytesWarning
            DeprecationWarning
            FutureWarning
            ImportWarning
            PendingDeprecationWarning
            ResourceWarning
            RuntimeWarning
            SyntaxWarning
            UnicodeWarning
            UserWarning
    GeneratorExit
    KeyboardInterrupt
    SystemExit

2 个答案:

答案 0 :(得分:3)

只有在您希望以某种方式处理的程序中可能发生错误时,才应该使用它。可能存在可能发生的错误,例如内存错误,但除非您希望程序以某种方式做出反应,否则您不应该使用try-except块。

为了获得流畅的用户体验,抓住某些不受控制的异常(例如连接错误)也可能会很好,这样您就可以告诉用户发生了什么,他们可以尝试对其进行补救。

答案 1 :(得分:2)

Exceptions are raised when called code encounters a problem that it cannot solve itself. For example when arguments are invalid, or when resources it attempts to access are not responding properly. Exceptions are generally meant to be exceptional and while they may occur when performing things, the normal control flow would be without exceptions.

You should catch exceptions, whenever called code could potentially raise an exception which you can recover from. That part is very important: There is no use catching an exception when you cannot work around that failure. Only catch exceptions that you expect to be raised.

That may seem counter intuitive after I having said that exceptions are exceptional, so expecting them seems weird. But the point is that code could raise any exception. For example, there are a lot of different external factors that could cause perfectly working code to suddenly raise an exception that it would usually never do. So you don’t just catch any exception. Instead you catch those exceptions explicitly that you expect to be eventually raised from the code and that you can work with without affecting your overall program.

I go into a lot more detail about this in my answer to another question: Why is “except: pass” a bad programming practice?

So basically, catch a specific exception when the code you are calling could raise that one and you could recover from it. Asking the user for input and want to parse this? Catch the exception from the parser and ask the user to correct it. Performing a network request to some API? Catch a network exception and maybe retry it. Writing a library for consuming an API that then performs a network request? Do not catch the network exception but let the consumer of your code decide how to recover from it.

Also, if you don’t know what exceptions code could raise, check the documentation. Usually the relevant exceptions are documented. There’s always a possibility that some exceptions may occur outside of the control of the called code, e.g. MemoryError, but those are usually neither to be expected nor really recoverable anyway, so you shouldn’t really check for those.