Python 提供了丰富的异常类,用于处理不同类型的错误和异常情况。以下是一些常见的 Python 异常类及其使用场景:
基本异常类
- Exception
- 所有异常类的基类。通常不直接使用,而是用它的子类。
- BaseException
- 所有异常的基类。一般不直接使用,主要用于
try
和except
块中的广泛捕获。
- 所有异常的基类。一般不直接使用,主要用于
常见内置异常类
- ArithmeticError
- 算术运算错误的基类,包括
ZeroDivisionError
、OverflowError
和FloatingPointError
。
- 算术运算错误的基类,包括
- ZeroDivisionError
- 除以零时引发的异常。
try: result = 1 / 0 except ZeroDivisionError: print("除以零错误")
- 除以零时引发的异常。
- OverflowError
- 数值运算结果超出表示范围时引发的异常。
import math try: result = math.exp(1000) except OverflowError: print("数值超出表示范围")
- 数值运算结果超出表示范围时引发的异常。
- IndexError
- 使用序列中不存在的索引时引发的异常。
my_list = [1, 2, 3] try: element = my_list[5] except IndexError: print("索引超出范围")
- 使用序列中不存在的索引时引发的异常。
- KeyError
- 使用映射中不存在的键时引发的异常。
my_dict = {'a': 1} try: value = my_dict['b'] except KeyError: print("键不存在")
- 使用映射中不存在的键时引发的异常。
- AttributeError
- 尝试访问对象不存在的属性时引发的异常。
class MyClass: pass obj = MyClass() try: obj.some_attribute except AttributeError: print("属性不存在")
- 尝试访问对象不存在的属性时引发的异常。
- TypeError
- 操作或函数应用于错误类型的对象时引发的异常。
try: result = 'string' + 5 except TypeError: print("类型错误")
- 操作或函数应用于错误类型的对象时引发的异常。
- ValueError
- 操作或函数接收的参数具有正确的类型但不适当的值时引发的异常。
try: number = int('not_a_number') except ValueError: print("值错误")
- 操作或函数接收的参数具有正确的类型但不适当的值时引发的异常。
- ImportError
- 导入模块失败时引发的异常。
try: import non_existent_module except ImportError: print("模块导入失败")
- 导入模块失败时引发的异常。
- FileNotFoundError
- 尝试打开不存在的文件时引发的异常。
try: with open('non_existent_file.txt', 'r') as file: content = file.read() except FileNotFoundError: print("文件未找到")
- 尝试打开不存在的文件时引发的异常。
- IOError
- 输入/输出操作失败时引发的异常。在 Python 3 中,它是
OSError
的别名。try: with open('/path/to/file', 'r') as file: content = file.read() except IOError: print("I/O 操作失败")
- 输入/输出操作失败时引发的异常。在 Python 3 中,它是
- RuntimeError
- 发生不属于其他类别的运行时错误时引发的异常。
def function(): raise RuntimeError("运行时错误") try: function() except RuntimeError as e: print(e)
- 发生不属于其他类别的运行时错误时引发的异常。
- StopIteration
- 迭代器没有更多项目时引发的异常,用于指示迭代的结束。
my_iter = iter([1, 2, 3]) try: while True: print(next(my_iter)) except StopIteration: print("迭代结束")
- 迭代器没有更多项目时引发的异常,用于指示迭代的结束。
系统相关异常类
- SystemExit
- 使用
sys.exit()
函数时引发的异常,用于请求程序正常退出。import sys try: sys.exit() except SystemExit: print("系统退出")
- 使用
- KeyboardInterrupt
- 用户中断程序执行(通常是通过按
Ctrl+C
)时引发的异常。try: while True: pass except KeyboardInterrupt: print("程序被用户中断")
- 用户中断程序执行(通常是通过按
- MemoryError
- 内存分配失败时引发的异常。
try: l = [1] * (10 ** 10) except MemoryError: print("内存不足")
- 内存分配失败时引发的异常。
其他常见异常类
- AssertionError
- 断言语句失败时引发的异常。
try: assert 1 == 0 except AssertionError: print("断言失败")
- 断言语句失败时引发的异常。
- EOFError
- 输入函数(如
input()
)在未读取到任何数据时引发的异常。try: input("输入点什么:") except EOFError: print("未读取到任何数据")
- 输入函数(如
这些异常类覆盖了大多数常见的错误场景,但 Python 允许开发者定义自己的异常类来处理特定的错误条件。这些自定义异常类通常继承自 Exception
或其子类。
在 Django 的视图函数中,常见的异常处理主要涉及数据库操作、请求数据处理、权限验证等方面。以下是一些具体的异常类及其使用场景:
数据库操作相关异常
- DatabaseError
- 所有数据库异常的基类。 ```python from django.db import DatabaseError
try: # 数据库操作 except DatabaseError as e: print(“数据库错误:”, e) ```
- IntegrityError
- 数据完整性相关的异常,比如违反唯一性约束。 ```python from django.db import IntegrityError
try: # 数据库操作 except IntegrityError as e: print(“数据完整性错误:”, e) ```
- DataError
- 数据库操作过程中由于无效数据引发的错误,比如数据超出字段最大长度。 ```python from django.db import DataError
try: # 数据库操作 except DataError as e: print(“数据错误:”, e) ```
- OperationalError
- 数据库操作失败,比如连接丢失。 ```python from django.db import OperationalError
try: # 数据库操作 except OperationalError as e: print(“操作错误:”, e) ```
请求数据处理相关异常
- ValueError
- 处理请求数据时,数据类型或值不正确。
try: # 处理请求数据 value = int(request.POST.get('value')) except ValueError as e: print("值错误:", e)
- 处理请求数据时,数据类型或值不正确。
- KeyError
- 请求数据中缺少必要的键。
try: value = request.POST['value'] except KeyError as e: print("键错误:", e)
- 请求数据中缺少必要的键。
- MultiValueDictKeyError
- 请求数据中缺少多值字典的键。 ```python from django.utils.datastructures import MultiValueDictKeyError
try: value = request.POST[‘value’] except MultiValueDictKeyError as e: print(“多值字典键错误:”, e) ```
权限验证相关异常
- PermissionDenied
- 用户没有执行某个操作的权限。 ```python from django.core.exceptions import PermissionDenied
def my_view(request): if not request.user.has_perm(‘app_label.permission_codename’): raise PermissionDenied(“没有权限”) ```
HTTP相关异常
- Http404
- 请求的资源不存在。 ```python from django.http import Http404
def my_view(request, pk): try: obj = MyModel.objects.get(pk=pk) except MyModel.DoesNotExist: raise Http404(“对象不存在”) ```
Django REST framework(DRF)中的异常
如果你使用的是 Django REST framework,这里有一些常用的异常类:
- ValidationError
- 序列化和反序列化时验证失败。 ```python from rest_framework.exceptions import ValidationError
def my_view(request): try: # 验证数据 serializer = MySerializer(data=request.data) serializer.is_valid(raise_exception=True) except ValidationError as e: print(“验证错误:”, e) ```
- NotAuthenticated
- 用户未进行身份验证。 ```python from rest_framework.exceptions import NotAuthenticated
def my_view(request): if not request.user.is_authenticated: raise NotAuthenticated(“用户未认证”) ```
- PermissionDenied
- 用户没有执行某个操作的权限。 ```python from rest_framework.exceptions import PermissionDenied
def my_view(request): if not request.user.has_perm(‘app_label.permission_codename’): raise PermissionDenied(“没有权限”) ```
- NotFound
- 请求的资源不存在。 ```python from rest_framework.exceptions import NotFound
def my_view(request, pk): try: obj = MyModel.objects.get(pk=pk) except MyModel.DoesNotExist: raise NotFound(“对象不存在”) ```
在 Django 视图函数中处理异常时,通常需要返回一个合适的 HTTP 响应,告知客户端发生了什么错误。以下是一个处理多种异常的示例:
from django.http import JsonResponse, Http404
from django.db import DatabaseError, IntegrityError
from django.core.exceptions import PermissionDenied
from rest_framework.exceptions import ValidationError, NotAuthenticated, NotFound
def my_view(request):
try:
# 视图逻辑
pass
except ValueError as e:
return JsonResponse({"error": "值错误", "details": str(e)}, status=400)
except KeyError as e:
return JsonResponse({"error": "键错误", "details": str(e)}, status=400)
except MultiValueDictKeyError as e:
return JsonResponse({"error": "多值字典键错误", "details": str(e)}, status=400)
except DatabaseError as e:
return JsonResponse({"error": "数据库错误", "details": str(e)}, status=500)
except IntegrityError as e:
return JsonResponse({"error": "数据完整性错误", "details": str(e)}, status=400)
except PermissionDenied as e:
return JsonResponse({"error": "没有权限", "details": str(e)}, status=403)
except Http404 as e:
return JsonResponse({"error": "对象不存在", "details": str(e)}, status=404)
except ValidationError as e:
return JsonResponse({"error": "验证错误", "details": str(e)}, status=400)
except NotAuthenticated as e:
return JsonResponse({"error": "用户未认证", "details": str(e)}, status=401)
except NotFound as e:
return JsonResponse({"error": "对象不存在", "details": str(e)}, status=404)
except Exception as e:
return JsonResponse({"error": "未知错误", "details": str(e)}, status=500)
这种方式确保了视图函数在处理不同类型的异常时,能够返回合适的响应和状态码。
在 Django 视图函数中调用自行封装的 S3 删除文件函数时,可能会遇到与 S3 操作相关的异常。以下是一些常见的异常处理方法和示例代码:
常见 S3 异常
如果使用的是 Boto3 库与 AWS S3 交互,以下是一些常见的异常类:
- botocore.exceptions.NoCredentialsError
- 未找到 AWS 凭证。
- botocore.exceptions.PartialCredentialsError
- AWS 凭证不完整。
- botocore.exceptions.EndpointConnectionError
- 无法连接到指定的 S3 端点。
- botocore.exceptions.ClientError
- 通用客户端错误。
示例代码
以下是一个在视图函数中调用 S3 删除文件函数并处理可能的异常的示例:
from django.http import JsonResponse
from botocore.exceptions import NoCredentialsError, PartialCredentialsError, EndpointConnectionError, ClientError
def delete_s3_file(file_key):
# 自行封装的 S3 删除文件函数
import boto3
s3_client = boto3.client('s3')
try:
s3_client.delete_object(Bucket='your-bucket-name', Key=file_key)
return True
except NoCredentialsError:
raise Exception("AWS 凭证未找到")
except PartialCredentialsError:
raise Exception("AWS 凭证不完整")
except EndpointConnectionError:
raise Exception("无法连接到 S3 端点")
except ClientError as e:
raise Exception(f"S3 客户端错误: {e}")
def my_view(request):
file_key = 'path/to/your/file'
try:
# 调用 S3 删除文件函数
delete_s3_file(file_key)
return JsonResponse({"message": "文件删除成功"}, status=200)
except NoCredentialsError as e:
return JsonResponse({"error": "AWS 凭证未找到", "details": str(e)}, status=500)
except PartialCredentialsError as e:
return JsonResponse({"error": "AWS 凭证不完整", "details": str(e)}, status=500)
except EndpointConnectionError as e:
return JsonResponse({"error": "无法连接到 S3 端点", "details": str(e)}, status=500)
except ClientError as e:
return JsonResponse({"error": "S3 客户端错误", "details": str(e)}, status=500)
except Exception as e:
return JsonResponse({"error": "未知错误", "details": str(e)}, status=500)
异常处理的考虑
- 统一异常处理:为了减少重复代码,可以将 S3 异常处理提取到一个单独的函数中。
- 日志记录:在捕获异常时,可以使用 Django 的日志记录功能记录详细的异常信息,以便后续分析和排查问题。
- 用户友好:返回的错误信息应尽可能对用户友好,不泄露内部实现细节,同时保留足够的信息供开发者调试。
统一异常处理的示例
import logging
from django.http import JsonResponse
from botocore.exceptions import NoCredentialsError, PartialCredentialsError, EndpointConnectionError, ClientError
logger = logging.getLogger(__name__)
def handle_s3_exception(e):
if isinstance(e, NoCredentialsError):
return JsonResponse({"error": "AWS 凭证未找到"}, status=500)
elif isinstance(e, PartialCredentialsError):
return JsonResponse({"error": "AWS 凭证不完整"}, status=500)
elif isinstance(e, EndpointConnectionError):
return JsonResponse({"error": "无法连接到 S3 端点"}, status=500)
elif isinstance(e, ClientError):
return JsonResponse({"error": f"S3 客户端错误: {e}"}, status=500)
else:
return JsonResponse({"error": "未知错误", "details": str(e)}, status=500)
def delete_s3_file(file_key):
import boto3
s3_client = boto3.client('s3')
try:
s3_client.delete_object(Bucket='your-bucket-name', Key=file_key)
return True
except (NoCredentialsError, PartialCredentialsError, EndpointConnectionError, ClientError) as e:
logger.error(f"S3 错误: {e}")
raise e
except Exception as e:
logger.error(f"未知错误: {e}")
raise e
def my_view(request):
file_key = 'path/to/your/file'
try:
delete_s3_file(file_key)
return JsonResponse({"message": "文件删除成功"}, status=200)
except Exception as e:
return handle_s3_exception(e)
这样可以简化视图函数中的异常处理逻辑,并确保异常处理的一致性。