Home  >  Article  >  Backend Development  >  python exception handling summary

python exception handling summary

WBOY
WBOYOriginal
2016-12-05 13:27:151019browse

项目 Recently, doing a small project often encounters the abnormalities of Python, which makes people very headache. Therefore, it is organized to avoid abnormalities to avoid being at a loss next time. The following is the organizational of Python abnormalities.

1.Python exception class

ExceptionDescriptionNameErrorTrying to access an undeclared variableZeroDivisionErrorThe divisor is 0SyntaxErrorGrammar errorIndexErrorIndex outside sequence rangeKeyErrorRequesting a dictionary key that does not existIOErrorInput and output errors (for example, the file you want to read does not exist)AttributeErrorTrying to access unknown object propertyValueErrorThe parameter type passed to the function is incorrect, such as passing characters to the int() function

2. Catching exceptions

Python’s complete exception catching statement looks a bit like:

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

Um...is it complicated? Of course, when we want to catch an exception, we don't have to write it down completely in the above format. We can throw away the else statement or the finally statement; we don't even need the exception statement, but keep the finally statement. Um, fainted? Okay, let’s explain them one by one.

2.1 try...except... statement

Try_suite Needless to say, everyone knows that it is the code we need to catch exceptions. The except statement is the key. After our try captures the exception in the code segment try_suite, it will be handled by except.

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

try:
 try_suite
except:
 exception block
  

 The above except clause is not followed by any exceptions and exception parameters, so no matter what exception the try catches, it will be handed over to the exception block of the except clause for processing. What if we want to handle a specific exception, for example, we only want to handle the division-by-zero exception, and if other exceptions occur, let them be thrown without handling them. What should we do? At this time, we have to pass in the exception parameter to the except clause! That ExceptionN is the exception class we want to give to the except clause (please refer to the table of exception classes), which means that if this type of exception is caught, it will be handled by this except clause. For example:

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! So what if I want to catch and handle multiple exceptions? There are two ways, one is to pass multiple exception class parameters to an except clause, the other is to write multiple except clauses, and each clause passes in the exception class parameters you want to handle. Even, these two usages can be mixed and matched! 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

Everyone can understand the above example at a glance, so I won’t explain it anymore. As long as everyone understands that our except can handle one exception, multiple exceptions, or even all exceptions.

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

>>> 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, which can be seen through type.

2.2 try...except...else statement

Now let’s talk about this else statement. There are many special uses of else in Python, such as for conditionals and loops. Putting it in a try statement, its effect is almost the same: when no exception is detected, the else statement is executed. Let’s give an example to help you understand better:

>>> 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 caught\n")
... 
>>> f.close()

2.3 finally statement

The finally clause is a piece of code that will be executed regardless of whether an exception is detected. We can throw away the except clause and else clause and use try...finally alone, or in combination with except, etc.

For example, in the example of 2.2, if other exceptions occur that cannot be caught and the program exits abnormally, then the file f will not be closed normally. This is not the result we want to see, but if we put the f.close statement into the finally statement, the file will be closed normally regardless of whether there is an exception. Wouldn't it be great

Copy code

>>> 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 caught\n")
... finally: 
>>>  f.close()

3. Two special and convenient methods for handling exceptions

3.1 Assert

What is an assertion? Let’s look at the syntax first:

assert expression[,reason]

Where assert is the keyword of assertion. When executing this statement, the expression is first 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 exception class instance we talked about before. don't know? It doesn’t matter, give me an example! The most practical!

>>> 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 assert is true, nothing will be done. If it is not true, an AssertionErro exception will be thrown, and the string we pass in will exist as the specific information of the instance of the exception class. . In fact, assert exceptions can also be caught by try blocks:

>>> 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 after the task ends, then you are in luck! This with statement can free you from try, except, and finally! The syntax is as follows:

with context_expr [as var]:
with_suite

Don’t you understand? It’s normal, give me an example!

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

上面这几行代码干了什么?

    (1)打开文件/root/test.py

    (2)将文件对象赋值给  f

    (3)将文件所有行输出

    (4)无论代码中是否出现异常,Python都会为我们关闭这个文件,我们不需要关心这些细节。

    这下,是不是明白了,使用with语句来使用这些共享资源,我们不用担心会因为某种原因而没有释放他。但并不是所有的对象都可以使用with语句,只有支持上下文管理协议(context management protocol)的对象才可以,那哪些对象支持该协议呢?如下表 

file

decimal.Contex 

thread.LockType 

threading.Lock 

threading.RLock 

threading.Condition 

threading.Semaphore 

threading.BoundedSemaphore

至于什么是上下文管理协议,如果你不只关心怎么用with,以及哪些对象可以使用with,那么我们就不比太关心这个问题

4.抛出异常(raise)

如果我们想要在自己编写的程序中主动抛出异常,该怎么办呢?raise语句可以帮助我们达到目的。其基本语法如下:

raise [SomeException [, args [,traceback]] 
第一个参数,SomeException必须是一个异常类,或异常类的实例

第二个参数是传递给SomeException的参数,必须是一个元组。这个参数用来传递关于这个异常的有用信息。

第三个参数traceback很少用,主要是用来提供一个跟中记录对(traceback)
下面我们就来列举几个 例子:

>>> raise NameError
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
NameError
>>> raise NameError() #异常类的实例
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") #注意跟上面一个例子的区别
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") #注意跟上面一个例子的区别
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
NameError: ('There is a name error', 'in test.py')

 其实,我们最常用的还是,只传入第一个参数用来指出异常类型,最多再传入一个元组,用来给出说明信息。如上面第三个例子。

5.异常和sys模块

另一种获取异常信息的途径是通过sys模块中的exc_info()函数。该函数回返回一个三元组:(异常类,异常类的实例,跟中记录对象)

>>> 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'> #异常类    
integer division or modulo by zero #异常类的实例
<traceback object at 0x7f538a318b48> #跟踪记录对象

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn