[Everything is fine, you can learn it] The exceptions and solutions that you will encounter when learning Python is running

When our computer programs are running, errors sometimes occur due to various uncontrollable reasons. For example: the required file cannot be found, network errors, incorrect user input, etc. At this time, the computer program will be unable to continue to run, or even exit directly. For example: Our common mobile APP crashes, the website has a 500 error, or the following error in Windows:
insert image description here
I believe everyone will be very annoyed when encountering such a situation? For programs written in Python. When Python detects an error, the interpreter cannot continue to execute, but some error prompts appear. This is the so-called "Python exception". Therefore, in order for our program to run stably for a long time, you need to know how to handle exceptions correctly.

Your three links (likes, favorites, comments) are the driving force for my continuous output, thank you.
Learn in interest, the benefits are beyond imagination, interesting source code and learning experience, tool installation package, welcome to add my WeChat: bobin1124, to communicate , learn and share together.

1. Introduction to Python exceptions

1. Exceptions in Python programs

Having said so much earlier, what exactly is a Python exception? Don't worry, let's take a look at how exceptions in Python programs are presented.

insert image description here

As shown in the figure above, when we want to run the python program file test.py, after typing in the terminal and pressing Enter, a string of information will appear after python test.py" " on the screen :-----test--1---

Traceback (most recent call last):

  File "C:/workspace/boxuegu/exception/test.py", line 2, in <module>

    open('123.txt','r')

FileNotFoundError: [Errno 2] No such file or directory: '123.txt'

This is the Python exception message. The exception in the picture means that an error occurred in the second line of the file test.py, which is an 输入输出型error numbered 2 " ", and 123.txtthe file named " " does not exist.

Why is there such an exception? Let's take a look at what the source code of the python program file called test.py looks like:

print('-----test--1---')

open('123.txt','r')

print('-----test--2---')

Corresponding to the running results, we can see that the original program had to print " " after the open() operation to open the file, -----test--2---but the result did not execute the -----test--2---action of printing " ".

This is because we are using the open() function to try to open a file " " that does not exist 123.txt. When 123.txtthe file " " cannot be found, the program will throw us a FileNotFoundErrortype of error, No such file or directory: 123. txt" (there is no such file or directory as 123.txt).

When Python detects an error and cannot handle it, there will be some error prompts, which are called "exceptions". If the exception has not been handled, the program will be forced to exit execution.

2. Common exceptions and inheritance structures

In Python, an exception is represented by an object, which stores information about the exception. Some of the exceptions we often encounter when programming are:

insert image description here

In addition to the above-mentioned common exceptions, in Python 3, there are other kinds of built-in exceptions. Here we list some examples

insert image description here

The complete Python 3 built-in exceptions can be found on the Python official website: https://docs.python.org/3/tutorial/errors.html

In Python, all exceptions and errors inherit from the base class BaseException. But in actual development, we will deal more with the parent class of Exception. Exception inherits from BaseException and implements the common methods we need to handle exceptions. Python's built-in exceptions also mostly inherit from Exception, and use their own exception descriptions as names. The naming rules are often AbcException or XyzError.

insert image description here

2. Exception handling

1. Catch the exception

First of all, as a computer, it needs us to tell it where there may be exceptions and what kind of exceptions there will be, that is, the capture of exceptions.

In Python, similar to other languages, we use try...except... to catch exceptions.

insert image description here
Take a look at the following code example:

try:

    print('-----test--1---')

    open('123.txt','r')

    print('-----test--2---')

except IOError:

    pass

It can be seen that the second paragraph " -----test--2---" is also not printed out, but the program exits normally. This is because, here we use try and except to capture the IOError exception and add a processing method. Therefore, the print('-----test–2—') statement is not executed.

We use the try keyword to contain logic codes, indicating that exceptions may occur here and need to be handled. If an exception occurs when the program executes to a certain statement, it will not continue to execute, but immediately look for the except statement following the try, and enter the code included in the except to execute. This is exception catching.

The pass in the except keyword means that although the exception is caught, nothing will be done; if the pass is changed to a print statement, then other information will be output. In other words, other logic we want can also be executed here, such as common exception handling logic such as disconnecting, closing files, releasing resources, and recording logs. This is Python's exception handling.

To sum up, try...catch... is used as follows:

  1. Put the code that may have problems in try
  2. Put the exception handling code in except, when an exception occurs, the system will interrupt the subsequent code execution and enter the code in except.

2.except captures multiple exceptions

First of all, we know that according to the exception type passed to except, we can specify to capture and handle a specific type of exception, as follows

try:
    print(num)

except IOError:

    print('产生错误了')

In the above program, we have used except to catch exceptions, but why do we still see error messages?

The result is as follows:

insert image description here

The answer is: the type of error captured by except is IOError, and the exception generated by the program at this time is NameError, so except does not take effect.

So we slightly modify the code, as follows:

try:
   print(num)

except NameError:

    print('产生错误了')

The result after running again is:

insert image description here
It can be seen that after changing IOError to NameError, you can successfully enter the except statement to catch the exception. From this, we know that after the except needs to correspond to the correct type of exception, it will enter the corresponding error handling code.

In addition to catching a single exception, we can also catch multiple exceptions, which is very common in actual development. Python also provides good support for this, see the following example:

#coding=utf-8
try:

    print('-----test--1---')

    open('123.txt','r') # 如果 123.txt 文件不存在,那么会产生 IOError 异常

    print('-----test--2---')

    print(num)# 如果 num 变量没有定义,那么会产生 NameError 异常

 

except (IOError,NameError):


    #如果想通过一次 except 捕获到多个异常可以用一个元组的方式

It can be seen that when catching multiple exceptions, you can put the type name of the exception to be caught after except and pass it in a tuple. In this way, whether it is IOError or NameError, it will enter the except code block.

3. Obtain the information description of the exception

In addition to interrupting the program, how else can it be handled? The most common is: print or log the abnormal information, so that we can view the abnormal content later by outputting the results.
As we mentioned earlier, exceptions in Python are defined by classes. Therefore, we need to obtain the exception class instance to access the exception information. Remember: through the as keyword, we can use the exception object instance in the except statement, as follows:

try:
   print(a)

except NameError as result:

    print(result)

In the above example, result is the instantiated object of NameError, we can print it directly in the except code block, and the program will output the description of the error. This is the same as the error output of the system when we write our own code and encounter an error.

A similar approach can also be used for multiple exceptions:

try:
  open('a.txt')

except (NameError, IOError) as result:

    print("哎呀,捕获到了异常")

    print("异常的基本信息是: ", result)

The result of the operation is as follows:

insert image description here

In this way, we can record the error information to other output sources such as logs or email notifications, so that we can better maintain the system.
insert image description here

4. Handle different exceptions separately

How to perform different logic processing for different types of exceptions? Very simple, the usage of except is very similar to the usage of the logical judgment keyword if. We can use multiple excepts to handle a variety of different exceptions, and enter different follow-up code logic according to the type of exception passed, as follows:

try:
 print(num)

except NameError:

    print('产生了命名错误')

except IOError:

    print('产生了文件 IO 错误')

except:

    print('出现了其他异常')

In the above code, when a NameError occurs in the program contained in try, it will enter the first except, and output "a naming error occurred", and when an IOError occurs in the program in try, it will enter the second except. In one except, output "A file IO error occurred". And if there are other exceptions other than the above two exceptions, it will enter the last except.

Please note: it does not specify any exception type. Therefore, we can use except to handle different types of exception errors in different ways. Isn't this similar to multiple conditions in an if statement?

5. Use else to handle non-abnormal situations

Similar to the usage of if...else..., we can also use else to match with except! When no exception occurs, the code after entering else continues to run.

try:
 num = 100

    print(num)

except NameError as result:

    print("捕获到了异常, 信息是: ", result)

else:

    print("程序正常运行,没有异常。")

Please note: else refers to the logic that enters when there is no exception, not the logic that the code enters when no exception is caught.

Therefore, if in the above code, other types of exceptions other than NameError occur in the program and are not caught, neither the except statement nor the else statement will be executed, and the program will exit due to the exception.

Note: Python is different from other languages. It believes that using try...except...else can describe the logic control flow more clearly, while other languages ​​such as Java do not have the else control flow keyword.

6.try… finally…

As a program, such as closing the file, releasing the lock, returning the database connection to the connection pool, etc. The try...finally... statement is used to handle such situations. In the program, if a piece of code must be executed, that is, it must be executed regardless of whether an exception occurs, then you need to use finally to wrap this code.

Let's look at the following example:

import time

try:

    f = open('test.txt')

    try:

        while True:

            content = f.readline()

            if len(content) == 0:

                break

            time.sleep(2)

            print(content)

    except:

        #如果在读取文件的过程中,产生了异常,那么就会捕获到

        #比如 按下了 ctrl+c

        pass

    finally:

        f.close()

        print('关闭文件')

except:

    print("没有这个文件")

Each line of data in the test.txt file is printed, and we intentionally use the time.sleep method to pause for 2 seconds before each line is printed. The reason for this is to make the program run slower. While the program is running, press to Ctrl+cinterrupt (cancel) the program.

In this way, we can observe that the KeyboardInterrupt exception is triggered and the program exits. But before the program exits, the finally clause is still executed, closing the file. This ensures that no matter whether the program is running correctly, it will not block some public resources such as files, networks, memory, etc., which improves the stability of the system and the rigor of the code logic.

7. Summary

We know that exception capture and processing are mainly composed of try/except/else/finally. Please keep in mind the following code examples:

try:
     # 正常的代码逻辑

except A:

     # Exception A 的处理逻辑

except B:

     # Exception B 的处理逻辑

except:

     # 其他异常的处理逻辑

else:

     # 如果没发生异常,执行这里

finally:

     # 无论是否发生异常,最后执行这里

#    

Python's exception handling seems complicated, but in fact, just remember the above summary rules.

Question: Which of the following combinations is an incorrect match?

A. try… except…

Wrong answer: try...except...is the most basic exception capture and processing method

B. try… else…

Correct answer: else must follow an except, so this is an incorrect usage

C. try … except…finally…

Wrong answer: Adding finally to try...except... can ensure that the code in finally is executed regardless of whether an exception occurs

D. try… finally…

Wrong answer: Not using except means not handling exceptions, but the code in finally will still be executed, and exceptions will be thrown upwards

insert image description here

3. Exception transmission

In the second level, we learned to use try to catch exceptions, and learned to use except and other methods to handle exceptions. Sometimes, our code may be encapsulated in a function body, which is called by other functions, and so on, which will generate a multi-layer function call stack. At this time, it may appear that the internal function does not have enough information to correctly handle the exception.

This involves a problem - the delivery of exceptions. The exception needs to be notified to its caller from the place where it originally occurred, so as to make correct exception handling. You may think it's complicated, but in fact, Python's exception passing is very simple and intuitive.

1.try nested pass

In Python, if we don't use except to handle exceptions, then exceptions will be 外层passed to " ".
The first delivery process is to pass to the outer layer of the try statement. If there is another try statement nested in the outer layer, the outer try statement will catch this exception. See the example below:

import time

try:

    f = open('test.txt')

    try:

        print(num)

    finally:

        f.close()

        print('关闭文件')

except:

    print("发生了错误")

test.txtWhen there is no ' ' file in the same directory as this code file, we will get the following results when we run it:

insert image description here
When ' test.txt' exists, run the above code, we will see the following result:

insert image description here
It can be seen that the second try statement prints the variable that does not exist, and a NameError will be generated. After the closing file in the finally statement is executed, the exception is caught by the except corresponding to the outer nested try statement.

To sum up : For the code contained in try, if no exception is used to catch the exception, the exception will be passed to the outer layer until it encounters the try and except of the next layer.

2. Function call passing

Using multiple try nested exceptions is a code that we rarely write. In actual projects, we more often see: in the multi-level call of the function, the called function has an exception.
Similar to the previous example, if the exception is not caught in the function, it will be passed to the caller of the function layer by layer until it encounters try and the corresponding except to catch it. Consider the following example:

def test1():

    print("----test1-1----")

    print(num)

    print("----test1-2----")
def test2():

    print("----test2-1----")

    test1()

    print("----test2-2----")

def test3():

    try:

        print("----test3-1----")

        test1()

        print("----test3-2----")

    except Exception as result:

        print("捕获到了异常,信息是:%s" % result)

 

    print("----test3-2----")

test3()

print("------华丽的分割线-----")

test2()

print("这里永远也不会被执行")

The result after running is as follows:

insert image description here
It can be seen that when test3() is called for the first time, the exception generated in test1() is caught by try...except...in test3(), and the error message is printed out. The system continues to execute, and there is no exception handling in the second test2(), then the exception of test1() is passed upwards until there is no code to handle it, and the program is finally interrupted. This is function call passing and requires you to understand memory.
insert image description here

4. Custom exceptions

1. Use raise to throw a custom exception

We have learned how to catch and handle exceptions. At the same time, we can also actively pass exceptions to the outer caller for the code logic we write, also called " ", 抛出异常to tell others that the program has generated an error.
We already know that all exceptions are subclasses of Python's built-in Exception class, so we can define a class that inherits from Exception as a custom exception, as follows:

class ShortInputException(Exception):

    '''自定义的异常类'''

    def __init__(self, length, atleast):

        #super().__init__()

        # 我们可以向类中添加属性

        self.length = length

        self.atleast = atleast

In Python, we can use the raise statement to throw an exception, continuing our example:

class ShortInputException(Exception):

    '''自定义的异常类'''

    def __init__(self, length, atleast):

        #super().__init__()

        # 我们可以向类中添加属性

        self.length = length

        self.atleast = atleast
def main():

    try:

        s = input('请输入 --> ')

        if len(s) < 3:

            # raise 引发一个你定义的异常

            raise ShortInputException(len(s), 3)

    except ShortInputException as result:#x 这个变量被绑定到了错误的实例

        print('ShortInputException: 输入的长度是 %d,长度至少应是 %d'% (result.length, result.atleast))

    else:

        print('没有异常发生.')
main()

The result of the operation is as follows:

insert image description here
In the above code, first, we have customized an exception class ShortInputException, which inherits the Exception parent class; then, when we use raise ShortInputException in the code to throw an exception, in the subsequent except, we specify the type of the received exception as ShortInputException, you can catch it; finally, we assign the exception object to the result variable through the as operator. In this way, we can access its length and atleast properties in the body of except.

Please note : In the above program, the description of the code #super(). init ():
This line of code can be called or not. But it is recommended that you call it, because the __init__ method is generally used to initialize the created object. If the parent class __init__ method is rewritten in the subclass, it means that a lot of initialization work in the parent class is not Doing so does not guarantee the stability of the program. So in your future development, if you rewrite the __init__ method of the parent class, it is best to call this method of the parent class first, and then add your own functions.

insert image description here

5. Abnormal application and summary

1. Unusual application

In the actual project code, we also need to determine which codes need exception handling, that is: predict exceptions.
Here we are generally based on the following principle: "Code that depends on the external environment and is uncontrollable needs to catch and handle exceptions." Common exception application scenarios include:

  1. User input: Not sure what data the user will enter to cause an error
  2. Network connection: The network connection may be interrupted
  3. File read and write: file may not exist
  4. Database lookup: the data you want to look up may not exist
  5. Remote API call: The input parameters, URL, etc. may be incorrect or the other party’s service may have an error

Wait, there are many other unusual application scenarios

2. Exception handling principle

When you encounter a qualified exception scenario, you can use ry to catch the exception. And after capturing, how to deal with the exception? Our principle is: "Let the program resume running".

Therefore, the logic in the except statement, in addition to logging and printing errors, we also try to make the program continue to run. For example, if a network error occurs, try to reconnect; if the database cannot be found, an empty list will be returned, and so on. Especially in some long-running programs and services, correct exception handling is extremely important.

You can look at the code you have written in the past to see where there may be undefined errors in the system. Then try to add try except exception handling, so that your system can respond correctly and run stably.

insert image description here

If you have mastered the above content, you can use exception handling to make your program run stably for a long time. Even if you encounter errors, you can quickly and correctly handle them and restore normal operation.

Guess you like

Origin blog.csdn.net/weixin_57577264/article/details/120686077