Python中异常处理的最佳实践:十个示例
在 Python 中,异常处理是一种机制,用于检测和管理程序运行过程中的错误。以下是一些关于异常处理的优秀实践示例:
使用 try/except 块:
def divide_numbers(a, b):
try:
return a / b
except ZeroDivisionError:
print("Cannot divide by zero!")
return None
result = divide_numbers(10, 5)
if result is not None:
print(result)
明确异常类型:
def validate_email(email):
try:
emailaddress = email.lower()
# 检查常见的无效邮箱格式
if '@' not in emailaddress or '.' not in emailaddress:
raise ValueError("Invalid email format.")
return email
except ValueError as ve:
print(ve)
return None
email = "invalid_email@domain.com"
validated_email = validate_email(email)
if validated_email is not None:
print(validated_email)
使用 finally 块清理资源:
def open_file(filename, mode):
try:
f = open(filename, mode))
return f
except FileNotFoundError:
print(f"{filename} not found!"))
return None
finally:
if 'f' in locals(): # check for 'f' in locals()
f.close() # close the file
filename = "example.txt"
opened_file = open_file(filename, "r")
if opened_file is not None:
print(opened_file.read()))
避免过度处理异常:
def safe_division(a, b):
try:
result = a / b
return result
except ZeroDivisionError:
# 返回一个有意义的值,如 -1
return -1
division_result = safe_division(10, 5)
print(division_result) # 输出:2.0
利用 logging 追踪错误:
import logging
def setup_logger(filename, level=logging.INFO):
logger = logging.getLogger(__name__)
logger.setLevel(level)
handler = logging.FileHandler(filename)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
filename = "error_log.txt"
logger = setup_logger(filename, level=logging.ERROR)
def some_function():
# 模拟可能引发错误的代码
nonexistent_attribute = some_object().nonexistent_attribute
try:
some_function()
logger.info("Some function executed successfully.")
with open(filename, "a")) as f:
f.write("Execution success logged to file.\n")
except Exception as e:
# 记录错误日志
logger.error(f"An error occurred during execution: {e}") )
with open(filename, "a")) as f:
f.write(f"{str(e)} - Error logging in file.\n") )
finally:
logger.removeHandler(handler) # 关闭日志处理器
避免全局异常处理:
class MyClass:
def some_method(self):
# 模拟可能会抛出异常的代码
try:
result = do_something()
return result
except SomeException as se:
self.handle_exception(se)
return None
def handle_exception(self, exception):
print(f"Handling error: {exception}")
# 这里可以添加自定义错误处理逻辑
my_instance = MyClass()
result = my_instance.some_method()
if result is not None:
print(result)
使用局部异常处理:
def divide_numbers(a, b):
try:
return a / b
except ZeroDivisionError:
# 这里是捕获到错误后执行的代码
print("Cannot divide by zero!")
return None
def some_function():
a = 10
b = 5
result = divide_numbers(a, b)
if result is not None:
print(f"Result: {result}")
try:
some_function()
except Exception as e:
print(f"An error occurred: {e}")
使用 with 语句处理文件或资源:
def open_and_read_file(filename):
try:
with open(filename, "r") as f:
content = f.read()
return content
except FileNotFoundError:
print(f"{filename} not found!"))
return None
filename = "example.txt"
file_content = open_and_read_file(filename)
if file_content is not None:
print(file_content)
对异常进行分级处理:
class CustomException(Exception):
pass
class NormalException(Exception):
pass
def some_function():
try:
# 正常业务逻辑代码
pass
except ZeroDivisionError as ze:
# 处理特定的异常,这里为除零错误
raise CustomException(f"Cannot divide by zero: {ze.__str__()}") from ze
except NormalException as ne:
# 可以对所有正常但需要处理的异常进行捕获并记录
print(f"Caught normal exception: {ne.__str__()}}")
finally:
# 对所有类型的异常进行统一的清理操作,如关闭连接等
pass
try:
some_function()
except Exception as e:
print(f"Encountered an error: {e}}")
- 结合日志和跟踪工具:
在处理复杂的系统或应用时,结合日志记录异常发生的时间、位置以及相关的上下文信息。同时,使用像 Sentry 这样的跟踪工具可以更好地帮助你定位问题的根源,并提供可能的解决方案。
import logging
sentry_integration = # 假设已集成 Sentry
# 设置日志级别和输出路径
logging.basicConfig(level=logging.ERROR, filename="app_errors.log", filemode="w")
def handle_exception(exception, logger):
try:
# 在日志中记录异常信息
logger.error(f"An error occurred: {exception.__str__()}"))
# 将异常发送到 Sentry
sentry_integration.capture exception
# 再次尝试处理异常,这里假设重新抛出一个特定的异常
raise ValueError("Failed to handle exception. Please check Sentry logs for more details.") from exception
except Exception as e:
# 如果在向上抛出异常的过程中又出现了新的异常,我们需要记录这个新出现的异常
logger.error(f"An unexpected error occurred while handling the original exception: {e.__str__()}"))
sentry_integration.capture exception
# 在需要处理异常的地方调用 handle_exception 函数
try:
some_function() # 假设在 some_function() 中发生了错误
except Exception as e:
handle_exception(e, logging.getLogger(__name__)))) # 将捕获的异常传递给 handle_exception 函数处理
```
还没有评论,来说两句吧...