Appearance
错误处理——try / except / finally
概念讲解
程序运行中难免出错:用户输入错误、网络断开、文件不存在……错误处理让程序在出错时不是崩溃,而是优雅地应对。
python
try:
# 尝试执行这段代码
risky_operation()
except 错误类型 as e:
# 如果出错,执行这里
handle_error(e)
else:
# 如果没出错,执行这里(可选)
success_path()
finally:
# 无论是否出错,都执行这里(可选)
cleanup()常见错误类型:
ValueError:值不合法TypeError:类型不匹配FileNotFoundError:文件不存在KeyError:字典的key不存在IndexError:列表索引越界
原则:
- 只捕获你预期会发生的错误
- 捕获后要处理,不要吞掉(空
except是坏习惯) - 必要时重新抛出异常(
raise)
代码示例
读取并解析配置文件
python
def parse_config(file_path):
"""读取配置文件,返回字典"""
config = {}
try:
with open(file_path, 'r', encoding='utf-8') as f:
for line_num, line in enumerate(f, 1):
line = line.strip()
if not line or line.startswith('#'):
continue # 跳过空行和注释
if '=' not in line:
print(f"警告:第{line_num}行格式错误,已跳过")
continue
key, value = line.split('=', 1)
config[key.strip()] = value.strip()
except FileNotFoundError:
print(f"配置文件不存在: {file_path},使用默认配置")
return {}
except PermissionError:
print(f"没有读取权限: {file_path}")
return {}
finally:
print("配置文件读取完毕")
return config
# 示例配置
# database = localhost
# port = 3306
# timeout = 30
result = parse_config('config.txt')
print(result)安全的类型转换
python
def safe_int(value, default=0):
"""尝试将值转换为整数,失败时返回默认值"""
try:
return int(value)
except (ValueError, TypeError):
return default
# 批量转换用户输入
user_inputs = ["42", "3.14", "hello", "", "100"]
numbers = [safe_int(x) for x in user_inputs]
print(numbers) # [42, 3, 0, 0, 100]自定义异常
python
class ValidationError(Exception):
"""数据验证失败异常"""
pass
def validate_age(age):
if not isinstance(age, (int, float)):
raise ValidationError(f"年龄必须是数字,得到: {type(age).__name__}")
if age < 0 or age > 150:
raise ValidationError(f"年龄超出正常范围: {age}")
return int(age)
try:
age = validate_age("twenty")
except ValidationError as e:
print(f"验证失败: {e}") # 验证失败: 年龄必须是数字,得到: str练习题
题目:写一个函数 divide_if_possible(a, b),返回 a除以b的结果。
要求:
- 如果 b 为 0,返回
None并打印"除数不能为零" - 如果 a 或 b 不是数字,返回
None并打印"参数类型错误" - 如果除法结果不是整数,返回浮点数(但小数部分不能超过0.0001)
参考答案
python
def divide_if_possible(a, b):
try:
if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):
print("参数类型错误")
return None
if b == 0:
print("除数不能为零")
return None
result = a / b
# 检查小数部分
fractional = result - int(result)
if result != int(result) and fractional > 0.0001:
return result
return int(result)
except Exception as e:
# 捕获其他未知错误(如NaN、无穷大)
print(f"未知错误: {e}")
return None
print(divide_if_possible(10, 3)) # 3.333... 返回
print(divide_if_possible(10, 2)) # 5
print(divide_if_possible(10, 0)) # 除数不能为零 None
print(divide_if_possible("a", 2)) # 参数类型错误 None关键思维:
try/except的粒度要合适,不要用空exceptisinstance检查比type() ==更准确(考虑继承)- 用
else分流成功路径也是一个好习惯