在学习Python编程时,遇到错误信息是很常见的情况。Python会通过错误提示来告诉我们程序哪里出了问题。了解这些错误信息并学会处理异常,是成为合格程序员的重要一步。
Python主要有两种错误类型:语法错误和异常。
语法错误是初学者最容易遇到的错误。这种错误发生在代码编写阶段,通常是因为没有遵守Python的语法规则。
比如下面这个例子:
# 错误的写法
while True print('Hello world')运行这段代码会显示:
SyntaxError: invalid syntax错误信息会指出问题所在的位置。在这个例子中,print前面缺少了冒号,正确的写法应该是:
# 正确的写法
while True:
print('Hello world')即使代码语法完全正确,运行时也可能出现问题,这种情况叫做异常。
常见的异常例子:
# 除以零错误
result = 10 * (1/0) # ZeroDivisionError: division by zero
# 使用未定义的变量
value = 4 + spam * 3 # NameError: name 'spam' is not defined
# 类型不匹配
text = '2' + 2 # TypeError: can only concatenate str (not "int") to str每种异常都有特定的类型,比如ZeroDivisionError、NameError、TypeError等。
我们可以使用try-except语句来捕获和处理异常。
# 处理用户输入错误
while True:
try:
number = int(input("请输入一个数字: "))
break # 如果输入正确,跳出循环
except ValueError:
print("输入的不是有效数字,请重新输入!")
print(f"你输入的数字是: {number}")一个try语句可以包含多个except子句,用于处理不同类型的异常。
try:
# 尝试打开文件并读取内容
with open('data.txt', 'r') as file:
content = file.read()
number = int(content.strip())
except FileNotFoundError:
print("文件不存在")
except ValueError:
print("文件内容不是有效的数字")
except Exception as e:
print(f"发生了未知错误: {e}")else子句中的代码只在try块没有发生异常时执行。
try:
number = int(input("请输入数字: "))
except ValueError:
print("输入的不是数字")
else:
# 只有在没有异常时才执行
result = number * 2
print(f"两倍结果是: {result}")finally子句中的代码无论是否发生异常都会执行。
try:
file = open('example.txt', 'r')
content = file.read()
number = int(content)
except (FileNotFoundError, ValueError) as e:
print(f"错误: {e}")
finally:
# 无论是否出错,都要关闭文件
file.close()
print("文件已关闭")def get_positive_number():
"""获取用户输入的正数"""
while True:
try:
number = float(input("请输入一个正数: "))
if number <= 0:
print("请输入大于0的数字")
continue
return number
except ValueError:
print("请输入有效的数字")
except KeyboardInterrupt:
print("\n程序被用户中断")
return None
# 使用示例
num = get_positive_number()
if num is not None:
print(f"你输入的数字是: {num}")def read_config_file(filename):
"""安全地读取配置文件"""
config = {}
try:
with open(filename, 'r', encoding='utf-8') as file:
for line_num, line in enumerate(file, 1):
line = line.strip()
if line and not line.startswith('#'): # 跳过空行和注释
try:
key, value = line.split('=', 1)
config[key.strip()] = value.strip()
except ValueError:
print(f"第{line_num}行格式错误: {line}")
except FileNotFoundError:
print(f"配置文件 {filename} 不存在")
except PermissionError:
print(f"没有权限读取文件 {filename}")
except UnicodeDecodeError:
print(f"文件编码错误,请使用UTF-8编码")
return config
# 使用示例
config = read_config_file('app.config')
print("配置内容:", config)import requests
def safe_download(url, timeout=10):
"""安全地下载网页内容"""
try:
response = requests.get(url, timeout=timeout)
response.raise_for_status() # 如果状态码不是200,抛出异常
return response.text
except requests.exceptions.Timeout:
print("请求超时,请检查网络连接")
except requests.exceptions.ConnectionError:
print("网络连接错误,请检查URL是否正确")
except requests.exceptions.HTTPError as e:
print(f"HTTP错误: {e}")
except Exception as e:
print(f"未知错误: {e}")
return None
# 使用示例
content = safe_download("https://fly63.com")
if content:
print("下载成功,内容长度:", len(content))我们可以使用raise语句主动抛出异常。
def validate_age(age):
"""验证年龄是否有效"""
if not isinstance(age, int):
raise TypeError("年龄必须是整数")
if age < 0:
raise ValueError("年龄不能为负数")
if age > 150:
raise ValueError("年龄不能超过150岁")
return True
# 测试
try:
validate_age(-5)
except ValueError as e:
print(f"验证失败: {e}")def process_order(amount, inventory):
"""处理订单"""
if amount <= 0:
raise ValueError("订单数量必须大于0")
if amount > inventory:
raise Exception(f"库存不足,当前库存: {inventory}")
print(f"订单处理成功,数量: {amount}")
return True
# 使用示例
try:
process_order(10, 5) # 库存只有5,要买10个
except Exception as e:
print(f"订单处理失败: {e}")我们可以创建自己的异常类,让错误处理更加精确。
class BankAccountError(Exception):
"""银行账户相关异常的基类"""
pass
class InsufficientFundsError(BankAccountError):
"""余额不足异常"""
def __init__(self, balance, amount):
self.balance = balance
self.amount = amount
super().__init__(f"余额不足。当前余额: {balance}, 需要: {amount}")
class InvalidAmountError(BankAccountError):
"""无效金额异常"""
pass
class BankAccount:
def __init__(self, initial_balance=0):
self.balance = initial_balance
def withdraw(self, amount):
if amount <= 0:
raise InvalidAmountError("取款金额必须大于0")
if amount > self.balance:
raise InsufficientFundsError(self.balance, amount)
self.balance -= amount
print(f"取款成功: {amount}, 当前余额: {self.balance}")
return amount
# 使用示例
account = BankAccount(1000)
try:
account.withdraw(1500) # 尝试取出1500,但余额只有1000
except InsufficientFundsError as e:
print(f"取款失败: {e}")
except BankAccountError as e:
print(f"账户操作失败: {e}")assert语句用于在代码中检查条件是否满足,如果不满足就抛出AssertionError。
def calculate_average(numbers):
"""计算数字列表的平均值"""
assert isinstance(numbers, list), "输入必须是列表"
assert len(numbers) > 0, "列表不能为空"
assert all(isinstance(x, (int, float)) for x in numbers), "列表元素必须是数字"
return sum(numbers) / len(numbers)
# 测试
try:
result = calculate_average([]) # 空列表
except AssertionError as e:
print(f"断言错误: {e}")with语句可以确保资源被正确释放,即使发生异常也不例外。
# 自动关闭文件
with open('data.txt', 'r') as file:
content = file.read()
# 即使这里发生异常,文件也会被正确关闭
numbers = [int(x) for x in content.split()]
# 文件已经自动关闭,不需要手动调用file.close()
print("处理完成,文件已自动关闭")import traceback
def debug_function():
try:
# 可能出错的代码
result = 10 / 0
except Exception as e:
print("错误类型:", type(e).__name__)
print("错误信息:", str(e))
print("详细的错误跟踪:")
traceback.print_exc()
debug_function()import logging
# 配置日志
logging.basicConfig(
filename='app.log',
level=logging.ERROR,
format='%(asctime)s - %(levelname)s - %(message)s'
)
def safe_operation():
try:
# 业务逻辑
risky_operation()
except Exception as e:
logging.error(f"操作失败: {e}", exc_info=True)
print("操作失败,详情请查看日志文件")
safe_operation()具体处理异常:不要简单地使用except:,应该捕获具体的异常类型
提供有用的错误信息:让用户知道发生了什么以及如何修复
不要过度使用异常:正常的程序流程不应该依赖异常处理
记录异常:在生产环境中记录异常信息以便调试
保持简洁:异常处理代码应该清晰易懂
# 好的做法
try:
value = int(user_input)
except ValueError:
print("请输入有效的整数")
# 不好的做法
try:
value = int(user_input)
except:
print("出错了") # 信息不具体,而且会捕获所有异常掌握异常处理技巧,能够让你的程序更加健壮和用户友好。记住,好的程序不仅要能正确处理正常情况,还要能优雅地处理异常情况。
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!