当我需要来自用户的输入数据或尝试启动线程时,我通常使用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
答案 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.