代碼異常處理try-except語法全解析,看完這篇文章寫的代碼更好維護穩定

try-except語法全解析

Whether you are developing Python, Java, JavaScript programs, or writing C++, PHP, GO, Ruby code, you cannot do without try … except exception handling.

As for why, it's all for the stable operation of the program/product/project.

If a program project, or to a smaller extent a file, does not have a try-except handling, then this program is vulnerable, unstable, and a program that can easily crash.


In code development, especially when developing framework projects, multiple modules (files) often call each other, either in one direction or bidirectionally. In such cases, if an exception occurs in the program, try-except only prints information based on the current location (I mean Except as e), making it difficult to locate the module call, i.e., the location of the source file. What I’m sharing today is how to locate the source file and line number.


Python try-except example:


In this example, we encapsulate the division operation code into a function named `divide`. The first parameter `a` of the function represents the dividend, and the second parameter `b` represents the divisor. In the function body, we use a try except statement to handle the division-by-zero exception. If the program does not encounter a `ZeroDivisionError` exception, the function will successfully compute the result and return it. If the program encounters a `ZeroDivisionError` exception, we will output the specific error message and return `None`.


```python

def divide(a, b):

    try:

        c = a / b

        return c

    except ZeroDivisionError as e:

        print(e)

        return None

# Call the function to perform division

result = divide(10, 0)

print(result)

```


Output result:


```

Divide by zero error

None

```


Locate the source file (error source)


Most of the time, in large projects or complex programs, simply printing `e` only displays basic error information. Sometimes it is difficult to pinpoint which file or which line of code the error occurred in based solely on this information. In such cases, a crude debugging method is to remove the try-except block and run the program again, letting it crash to reveal the specific details.


A relatively quick and convenient way to locate error information is to pinpoint the specific line and file where the error occurred. In fact, we can utilize the error object `e`, which has relevant properties that can be called.


```python

def divide(a, b):

    try:

        c = a / b

        return c

    except ZeroDivisionError as e:

# Print specific file name and line number via e's attribute

print(f"Error Occurred At, File: {e.__traceback__.tb_frame.f_code.co_filename}, Line: {e.__traceback__.tb_lineno}")

        print("Divide by zero error")

        return None

# Call function to perform division operation

result = divide(10, 0)

print(result)

```


Output result:


```

Error Occurred At, File: file path, Line: error line number

Divide by zero error

None

```


Or you can also use the built-in module `traceback` to achieve this.


```python

import traceback

import sys

def divide(a, b):

    try:

        c = a / b

        return c

    except ZeroDivisionError as e:

# Implement with traceback

        tb_list = traceback.extract_tb(sys.exc_info()[2])

        filename, line_no, func_name, code_str = tb_list[-1]

print(f"Error Occurred At, File: {filename}, Line: {line_no}")

print("Divide by zero error")

        return None

#Call function to perform division operation

result = divide(10, 0)

print(result)

```


Advanced Usage


At this point, there are still some issues: if the source error file is a third-party library or built-in library, such as a file located in the site-packages of the Python environment, then printing it out is not very useful. What we want to print is the error location of our own code, not the location information of errors from built-in modules or installed third-party modules. Only by finding the location of the custom code can we optimize and fix it.


You can use `traceback.extract_stack()` to replace `traceback.extract_tb()` in order to exclude the source code locations of third-party libraries.


```python

import traceback

import sys

def divide(a, b):

    try:

        c = a / b

        return c

    except ZeroDivisionError as e:

        # Implement with traceback

tb_list = traceback.extract_stack()[:-1] # The last item is the location of the current call, not where the exception occurred

filename, line_no, func_name, code_str = tb_list[-1]

        print(f"Error Occurred At, File: {filename}, Line: {line_no}")

print("Divide by zero error")

        return None

# Call the function to perform division operation

result = divide(10, 0)

print(result)

```


Use the `traceback.extract_stack()` method to obtain the complete stack trace information of where the exception occurred. Then, use list slicing to remove the last element, as this element represents the current call location rather than where the exception occurred. The last element typically contains the location of your calling code, so you do not want to include it. Then, extract the last source code file name, line number, function name, and code line from the available stack information to determine where the exception occurred.


This method will not include the source code locations of third-party libraries and will only extract source code locations related to your code.


You can also use the `currentframe()` function from the `inspect` module in the Python standard library to get the current frame. Then, you can use the `traceback.extract_stack()` method to extract stack information, and then use the stack information to progressively compare source file paths to find the source file path related to the current project.


```python

import os

import inspect

import traceback

def get_project_traceback():

    # Get current frame

    frame = inspect.currentframe()

# Extract stack information (the first two elements are the positions of filter and get_project_traceback functions themselves)

    tb_list = traceback.extract_stack(frame)[2:]

# Find the source file path related to the current project

    for filename, line_no, func_name, code_str in reversed(tb_list):

        if os.getcwd() in filename:

return filename, line_no, func_name, code_str

    # If none are found, return the last source file

        filename, line_no, func_name, code_str = tb_list[-1]

    return filename, line_no, func_name, code_str

def divide(a, b):

    try:

        c = a / b

        return c

    except ZeroDivisionError as e:

        filename, line_no, func_name, code_str = get_project_traceback()

        print(f"Error Occurred At, File: {filename}, Line: {line_no}")

print("Divide by zero error")

        return None

# Call the function to perform division operation

result = divide(10, 0)

print(result)

```


In the above code, the `get_project_traceback` function first uses the `inspect.currentframe()` function to obtain the current frame, then uses the `traceback.extract_stack(frame)` method to extract stack information. The first two elements are the positions of the filter and the `get_project_traceback` function itself, so it starts from the third element. Next, the function uses `os.getcwd()` to get the current project path, and compares each source file path one by one to find the source file path related to the current project. If none are found, it returns the last source file.


In the main code block, call the `get_project_traceback` function to obtain stack information related to the current project. When an exception occurs, this code segment retrieves the exception information and uses the `get_project_traceback` function to print the stack information related to the current project.


This article provides readers with practical tips for handling exceptions in Python, particularly an in-depth discussion on locating the source of errors and improving program stability. By using `try-except` statements and related tools, program crashes can be effectively avoided, thereby enhancing development efficiency and program quality.

关于我们

​我们致力于帮助中小企业实现数字化转型,我们的团队由一群充满激情和创新思维的专业人士组成,他们具备丰富的行业经验和技术专长。

扫一扫获取顾问以及手册

归档
登入 發表評論
Odoo 17如何設定庫存功能線路(Route)
odoo17路線功能