杰瑞科技汇

Python中getlasterror的作用是什么?

Of course! In Python, there isn't a single, universal function called GetLastError() like there is in the Windows API (e.g., in C++ or C#). This is because Python handles errors differently, primarily through its built-in exception handling mechanism.

Python中getlasterror的作用是什么?-图1
(图片来源网络,侵删)

However, depending on what you're trying to do, there are several ways to get information about the last error. Let's break it down by the most common scenarios.

The Pythonic Way: Exception Handling (The Best Practice)

This is the standard and recommended way to deal with errors in Python. Instead of checking for an error code after an operation, you wrap the code that might fail in a try...except block.

When an error occurs, Python raises an exception object. This object contains all the information you need about the error, including a message and a type.

try:
    # This code might raise an error
    result = 10 / 0
    # Another example: accessing a non-existent file
    # with open("non_existent_file.txt", "r") as f:
    #     content = f.read()
except Exception as e:
    # 'e' is the exception object that was raised
    print(f"An error occurred: {e}")
    print(f"Type of error: {type(e)}")
    # You can also get the traceback, which is the "call stack"
    # showing where the error happened.
    import traceback
    print("\n--- Full Traceback ---")
    traceback.print_exc()
    print("----------------------\n")
print("This line will still be executed if the error is handled.")

Output:

Python中getlasterror的作用是什么?-图2
(图片来源网络,侵删)
An error occurred: division by zero
Type of error: <class 'ZeroDivisionError'>
--- Full Traceback ---
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero
----------------------
This line will still be executed if the error is handled.

Key Takeaway: For general Python programming, you should almost always use try...except. It's cleaner, more readable, and more powerful than checking error codes.


Calling C Code (e.g., via ctypes)

If you are calling a function from a C library (like the Windows API) using Python's ctypes module, that C function will set a thread-local error code (like GetLastError() on Windows). In this specific case, you can retrieve that error code.

The Windows API provides GetLastError() to retrieve this code, and FormatMessage() to convert it into a human-readable string.

Here is a complete example of how to call a Win32 API function and get the last error.

Python中getlasterror的作用是什么?-图3
(图片来源网络,侵删)
import ctypes
from ctypes import wintypes
# Define the necessary Windows functions and constants
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
# Function prototypes
GetLastError = kernel32.GetLastError
GetLastError.argtypes = []
GetLastError.restype = wintypes.DWORD
FormatMessageW = kernel32.FormatMessageW
FormatMessageW.argtypes = [
    wintypes.DWORD, wintypes.LPCVOID, wintypes.DWORD,
    wintypes.DWORD, wintypes.LPWSTR, wintypes.DWORD,
    wintypes.LPVOID
]
FormatMessageW.restype = wintypes.DWORD
# Constants for FormatMessage
FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200
LANG_NEUTRAL = 0x00
SUBLANG_DEFAULT = 0x01
def get_last_win_error():
    """
    Gets the last error code from the Windows API and formats it into a string.
    """
    error_code = GetLastError()
    if error_code == 0:
        return "No error occurred"
    # Format the error message
    buffer_size = 256
    buffer = ctypes.create_unicode_buffer(buffer_size)
    FormatMessageW(
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        None,
        error_code,
        (LANG_NEUTRAL << 10) | SUBLANG_DEFAULT,
        buffer,
        buffer_size,
        None
    )
    return buffer.value
# --- Example Usage ---
# Try to open a file that doesn't exist.
# CreateFileW is a common Win32 API function that sets GetLastError() on failure.
CREATE_NEW = 1
GENERIC_READ = 0x80000000
INVALID_HANDLE_VALUE = wintypes.HANDLE(-1).value
# Define the CreateFileW function prototype
CreateFileW = kernel32.CreateFileW
CreateFileW.argtypes = [
    wintypes.LPCWSTR, wintypes.DWORD, wintypes.DWORD,
    wintypes.LPVOID, wintypes.DWORD, wintypes.DWORD,
    wintypes.HANDLE
]
CreateFileW.restype = wintypes.HANDLE
# The important part: tell ctypes to call GetLastError() if the function returns NULL
# This is done with the 'errcheck' argument
def check_null_handle(result, func, args):
    if result == INVALID_HANDLE_VALUE:
        raise ctypes.WinError(get_last_win_error())
    return result
CreateFileW.errcheck = check_null_handle
try:
    # This will fail
    handle = CreateFileW(
        "C:\\path\\to\\a\\file\\that\\does\\not\\exist.txt",
        GENERIC_READ,
        0,
        None,
        CREATE_NEW,
        0,
        None
    )
except OSError as e:
    print(f"Caught an OSError: {e}")
    # We can also manually get the last error if needed
    print(f"Manually retrieved last error: {get_last_win_error()}")

Output:

Caught an OSError: The system cannot find the path specified. (2)
Manually retrieved last error: The system cannot find the path specified.

In this example, we see two ways to get the error:

  1. ctypes.WinError() automatically calls GetLastError() and creates an OSError with the correct message.
  2. Our custom get_last_win_error() function manually calls GetLastError() and FormatMessageW to do the same thing.

The errno Module (For Low-Level System Calls)

When Python's built-in functions or methods fail due to an operating system-level error (e.g., open() failing because a file doesn't exist), they often raise an OSError. This exception has an .errno attribute, which corresponds to a C library error code defined in the errno module.

You can use the errno module to look up the meaning of the error code.

import os
import errno
try:
    # Try to open a directory for writing, which is not allowed
    # This will raise an IsADirectoryError, which is a subclass of OSError
    f = open("/etc", "w")
    f.write("test")
    f.close()
except OSError as e:
    print(f"An OSError occurred with errno: {e.errno}")
    # Use the errno module to get the error's name and description
    error_name = errno.errorcode.get(e.errno)
    error_description = os.strerror(e.errno)
    print(f"Error Name: {error_name}")
    print(f"Error Description: {error_description}")

Output:

An OSError occurred with errno: 21
Error Name: EISDIR
Error Description: Is a directory

Summary: Which One Should You Use?

Scenario Method Why?
General Python Code try...except Exception as e: This is the standard, Pythonic way. It's robust, readable, and handles all Python-level errors.
Calling C Libraries (e.g., Win32 API) ctypes + GetLastError() / FormatMessageW This is the direct equivalent of GetLastError(). Use it when interoperating with C code that sets error codes.
Low-Level OS Errors try...except OSError as e: + e.errno + errno module This is for when a system call (like opening a file) fails at the OS level. The errno module provides a mapping to standard error codes.
分享:
扫描分享到社交APP
上一篇
下一篇