Python error and exception summary

  • 2020-04-02 13:09:59
  • OfStack

Note that this is not a full introduction to Python exceptions, it is just a note note and summary of the nature of Python exceptions after learning them. What? You don't know what an anomaly is, uh...

1. The Python exception classes

Python is an object-oriented language, so exceptions thrown by programs are also classes. There are a few common Python exceptions that you can just glance at, have an image, and when you're programming, you're sure to see them more than once (unless you're not using Python).

abnormal describe NameError Attempt to access an undeclared variable ZeroDivisionError Divisor of 0 SyntaxError Grammar mistakes IndexError The index is out of sequence range KeyError Request a non-existent dictionary keyword IOError I/o error (e.g. the file you want to read does not exist) AttributeError Attempt to access unknown object properties ValueError The argument to the function is of an incorrect type, such as passing in a string to the int() function

2. Catch exceptions

      Python's complete statement for catching exceptions is something like:


try:
    try_suite
except Exception1,Exception2,...,Argument:
    exception_suite
......   #other exception block
else:
    no_exceptions_detected_suite
finally:
    always_execute_suite

Er... Isn't it complicated? Of course, when we want to catch an exception, we don't have to write it all down in that format, we can drop the else statement, or the finally statement; Not even the exception statement, but the finally statement. Uh, dizzy? Well, here we go.

2.1. Try... Except... statements

      Try_suite, as I said, is the code we need to catch exceptions. The except statement is the key, and after we try to catch the exception in the try_suite, we will hand it over to except.

      The try... The simplest form of the except statement is as follows:


try:
    try_suite
except:
    exception block

The above except clause does not follow any exceptions and exception parameters, so any exceptions caught by the try are handled by the exception block of the except clause. What if we want to handle a particular exception, say, we just want to handle the divide by zero exception, and if other exceptions occur, we just throw them out without doing anything? At this point, we pass in an exception parameter to the except clause! That ExceptionN is the exception class for the except clause (see the exception class table), which means that if such an exception is caught, it is left to the except clause to handle. Such as:


try:
    try_suite
except Exception:
    exception block

For example:


>>> try:
...     res = 2/0
... except ZeroDivisionError:
...     print "Error:Divisor must not be zero!"
... 
Error:Divisor must not be zero!

Look, we really caught the ZeroDivisionError exception! What if I want to catch and handle multiple exceptions? There are two ways: one is to pass in more than one exception class parameter to an except clause, and the other is to write more than one except clause, each passing in the exception class parameter that you want to handle. Even, these two usage can mix and match! Let me give you an example.


try:
    floatnum = float(raw_input("Please input a float:"))
    intnum = int(floatnum)
    print 100/intnum
except ZeroDivisionError:
    print "Error:you must input a float num which is large or equal then 1!"
except ValueError:
    print "Error:you must input a float num!"
[root@Cherish tmp]# python test.py 
Please input a float:fjia
Error:you must input a float num!
[root@Cherish tmp]# python test.py 
Please input a float:0.9999
Error:you must input a float num which is large or equal then 1!
[root@Cherish tmp]# python test.py 
Please input a float:25.091
4

As soon as you understand the above example, you won't explain it. As long as you understand that our except can handle one exception, many exceptions, or all exceptions.

      You may have noticed that we haven't explained what the Argument after the except clause is. Don't worry, just listen to me. The Argument is actually an instance of an exception class (don't tell me you don't know what an instance is), and it contains diagnostic information from the exception code. That is, if you catch an exception, you can get more information about the exception from an instance of the exception class. Such as:


>>> try:
...     1/0
... except ZeroDivisionError,reason:
...     pass
... 
>>> type(reason)
<type 'exceptions.ZeroDivisionError'>
>>> print reason
integer division or modulo by zero
>>> reason
ZeroDivisionError('integer division or modulo by zero',)
>>> reason.__class__
<type 'exceptions.ZeroDivisionError'>
>>> reason.__class__.__doc__
'Second argument to a division or modulo operation was zero.'
>>> reason.__class__.__name__
'ZeroDivisionError'

In the above example, we caught the divide by zero exception, but did nothing. That reason is an instance of the exception class ZeroDivisionError, as shown by type.

2.2 the try... Except... Else statements
      Now let's talk about this else statement. There are many special USES of else in Python, such as for conditions and loops. In a try statement, it does the same thing: when no exception is detected, the else statement is executed. Here's an example that might make sense to you:


>>> import syslog
>>> try:
...     f = open("/root/test.py")
... except IOError,e:
...     syslog.syslog(syslog.LOG_ERR,"%s"%e)
... else:
...     syslog.syslog(syslog.LOG_INFO,"no exception caughtn")
... 
>>> f.close()

The finally clause 2.3
      The finally clause is a piece of code that executes whether an exception is detected or not. We can drop the except and else clauses and use the try... In the first place, you can also use it with except.

For example, in the example of 2.2, if there are other exceptions that cannot be caught and the program exits, then file f is not closed normally. This is not the result we expected, but wouldn't it be nice if we put the f.lose statement in the finally statement and closed the file normally with or without an exception


>>> import syslog
>>> try:
...     f = open("/root/test.py")
... except IOError,e:
...     syslog.syslog(syslog.LOG_ERR,"%s"%e)
... else:
...     syslog.syslog(syslog.LOG_INFO,"no exception caughtn")
... finally: 
>>>     f.close()

  See, our example above actually USES try,except,else,finally! :-), isn't that interesting? By now, you've basically learned how to catch and handle regular exceptions in Python.

3. Two special and easy ways to handle exceptions

3.1 assert
      What is an assertion, first look at the syntax:


assert expression[,reason]

Assert is the keyword for assertions. When the statement is executed, the expression is evaluated. If the expression is true, nothing is done. If the expression is not true, an exception is thrown. Reason is the same as the instance of the exception class we talked about earlier. Don't understand? That's ok. Examples! The most really!


>>> assert len('love') == len('like')
>>> assert 1==1
>>> assert 1==2,"1 is not equal 2!"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: 1 is not equal 2!

We can see that if the expression after the assert is true, then nothing is done, if not, an AssertionErro exception is thrown, and the string we pass in exists as an instance of the exception class. In fact, assert exceptions can also be caught by the try block:


>>> try:
...     assert 1 == 2 , "1 is not equal 2!"
... except AssertionError,reason:
...     print "%s:%s"%(reason.__class__.__name__,reason)
... 
AssertionError:1 is not equal 2!
>>> type(reason)
<type 'exceptions.AssertionError'>

3.2. Context management (with statement)
    If you use try,except,finally code just to ensure the unique allocation of Shared resources (such as files, data) and release it when the task is over, then you're in luck! This with statement frees you from trying,except,finally! The syntax is as follows:


with context_expr [as var]:
    with_suite

Don't you understand? It's normal, for example!


>>> with open('/root/test.py') as f:
...     for line in f:
...         print line

What do these lines of code do?
      (1) open file /root/test.py
      (2) assign a value to the file object   f
      (3) output all lines of the file
        (4) Python closes the file for us regardless of whether there is an exception in the code, and we don't need to care about the details.
      Now, is it clear that using the with statement to use these Shared resources, we don't have to worry about not releasing them for some reason. But not all objects can use the with statement, only those that support the context management protocol. Which objects support the protocol? The following table:
The file

A decimal. The Context
Thread. LockType
Threading. Lock
Threading. RLock
When the Condition
When the Semaphore
Threading. BoundedSemaphore

      As for what is a context management protocol, if you don't just care about how to use with and which objects can use with, then we don't care too much :)

4. Raise an exception

      What if we want to throw an exception in our own program? The raise statement can help us achieve this. The basic syntax is as follows:


raise [SomeException [, args [,traceback]]

The first argument, SomeException must be an exception class, or an instance of an exception class
      The second parameter is the parameter passed to SomeException and must be a tuple. This parameter is used to pass useful information about the exception.
      The third parameter, traceback, is rarely used and is used to provide a trace object (traceback)
      Here are a few examples.


>>> raise NameError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError
>>> raise NameError()  # An instance of an exception class 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError
>>> raise NameError,("There is a name error","in test.py")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
>>> raise NameError("There is a name error","in test.py")  # Notice the difference from the above example 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: ('There is a name error', 'in test.py')
>>> raise NameError,NameError("There is a name error","in test.py")  # Notice the difference from the above example 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: ('There is a name error', 'in test.py')

In fact, the most common thing to do is to pass in only the first parameter to indicate the type of exception, and at most one tuple to provide explanatory information. As in the third example above.

5. Exceptions and sys modules

      Another way to get exception information is through the exc_info() function in the sys module. This function returns a triple :(exception class, instance of exception class, record object)


>>> try:
...     1/0
... except:
...     import sys
...     tuple = sys.exc_info()
... 
>>> print tuple
(<type 'exceptions.ZeroDivisionError'>, ZeroDivisionError('integer division or modulo by zero',), <traceback object at 0x7f538a318b48>)
>>> for i in tuple:
...     print i
... 
<type 'exceptions.ZeroDivisionError'> # Exception class     
integer division or modulo by zero # An instance of an exception class 
<traceback object at 0x7f538a318b48> # Trace object 


Related articles: