Learning Python3 in exceptionprocessingmechanism, includingerror捕获, processing and 自定义exception
exception is 程序执行过程in发生 error, 它会in断程序 正常执行流程. in Pythonin, exception is aobject, 表示程序执行过程in发生 error or exceptioncircumstances.
当Python程序遇 to error时, 会抛出一个exception. such as果不processing这个exception, 程序会终止并显示errorinformation. throughexceptionprocessing, 我们可以捕获并processing这些exception, 使程序able to继续执行.
common Pythonexceptionincluding:
SyntaxError: 语法errorNameError: 名称error, using了undefined variableTypeError: class型error, operation or functionapplication于不适当class型 objectValueError: 值error, operation or function接收 to class型正确但值不合适 parameterZeroDivisionError: 除零errorFileNotFoundError: file未找 to errorIndexError: indexerror, 序列in没 has 该indexKeyError: 键error, dictionaryin没 has 该键try-except语句 is Pythonin用于捕获 and processingexception basicstructure. 它 语法such as under :
try:
# 可能会引发exception code
pass
except [ExceptionType [as e]]:
# processingexception code
pass
当try块in code引发exception时, Python会跳转 to for 应 except块in执行exceptionprocessingcode.
# basic exceptionprocessing
try:
num = int(input("请输入一个number: "))
result = 10 / num
print(f"结果 is : {result}")
except:
print("发生了error!")
我们可以指定要捕获 specificexceptionclass型, 这样只 has 当引发 exception is 指定class型 or 其子class时, 才会执行 for 应 except块.
# 捕获specificexception
try:
num = int(input("请输入一个number: "))
result = 10 / num
print(f"结果 is : {result}")
except ValueError:
print("输入error, 请输入一个 has 效 number!")
except ZeroDivisionError:
print("error: 除数不能 for 零!")
except Exception as e:
print(f"发生了othererror: {e}")
我们可以 in 一个except块in捕获 many 个exceptionclass型, 将它们放 in 一个元组in.
# 捕获 many 个exception
try:
num = int(input("请输入一个number: "))
result = 10 / num
print(f"结果 is : {result}")
except (ValueError, ZeroDivisionError) as e:
print(f"发生了error: {e}")
else子句会 in try块in code没 has 引发exception时执行.
# usingelse子句
try:
num = int(input("请输入一个number: "))
result = 10 / num
except ValueError:
print("输入error, 请输入一个 has 效 number!")
except ZeroDivisionError:
print("error: 除数不能 for 零!")
else:
print(f"计算成功, 结果 is : {result}")
finally:
print("程序执行完毕. ")
finally子句无论try块 is 否引发exception都会执行, 通常用于执行cleanoperation, such as关闭file, 释放resourceetc..
# usingfinally子句
try:
f = open("example.txt", "r")
content = f.read()
print(content)
except FileNotFoundError:
print("file未找 to !")
finally:
# 无论 is 否发生exception, 都会执行这里 code
if 'f' in locals() and not f.closed:
f.close()
print("file已关闭. ")
# usingwith语句 (更简洁 方式)
try:
with open("example.txt", "r") as f:
content = f.read()
print(content)
except FileNotFoundError:
print("file未找 to !")
# with语句会自动关闭file, 不需要finally子句
我们可以usingraise语句手动抛出exception. 这 in 以 under circumstances under 很 has 用:
# 手动抛出exception
def divide(a, b):
if b == 0:
raise ZeroDivisionError("除数不能 for 零!")
return a / b
try:
result = divide(10, 0)
print(f"结果 is : {result}")
except ZeroDivisionError as e:
print(f"捕获 to exception: {e}")
我们也可以重 new 抛出exception, 将exception传递给 on 层调用者:
# 重 new 抛出exception
def process_data(data):
try:
# processingdata
if not data:
raise ValueError("data for 空!")
return len(data)
except ValueError as e:
print(f"processingdata时发生error: {e}")
# 重 new 抛出exception
raise
try:
result = process_data([])
print(f"processing结果: {result}")
except ValueError as e:
print(f" on 层捕获 to exception: {e}")
我们可以throughinheritanceExceptionclass or 其子class来creation自定义exceptionclass. 自定义exceptionclass通常用于表示specific于application程序 errorcircumstances.
# 自定义exceptionclass
class InvalidAgeError(Exception):
"""年龄无效exception"""
def __init__(self, age, message="年龄无效"):
self.age = age
self.message = message
super().__init__(self.message)
def __str__(self):
return f"{self.message}: {self.age}"
class NegativeAgeError(InvalidAgeError):
"""年龄 for 负exception"""
def __init__(self, age):
super().__init__(age, "年龄不能 for 负数")
# using自定义exception
def register_user(name, age):
if age < 0:
raise NegativeAgeError(age)
elif age < 18:
raise InvalidAgeError(age, "年龄必须满18岁")
print(f"user {name} register成功!")
try:
register_user("Alice", 25)
except InvalidAgeError as e:
print(f"register失败: {e}")
try:
register_user("Bob", 15)
except InvalidAgeError as e:
print(f"register失败: {e}")
try:
register_user("Charlie", -5)
except InvalidAgeError as e:
print(f"register失败: {e}")
creation一个user输入verificationfunction, usingexceptionprocessing来processing各种输入error.
class InputValidationError(Exception):
"""输入verificationexception"""
pass
class EmptyInputError(InputValidationError):
"""空输入exception"""
pass
class LengthError(InputValidationError):
""" long 度errorexception"""
pass
class FormatError(InputValidationError):
"""格式errorexception"""
pass
def validate_username(username):
"""
verificationuser名
Args:
username: user名
Returns:
bool: verification is 否成功
Raises:
EmptyInputError: such as果user名 for 空
LengthError: such as果user名 long 度不符合要求
FormatError: such as果user名格式不符合要求
"""
if not username:
raise EmptyInputError("user名不能 for 空")
if len(username) < 3 or len(username) > 20:
raise LengthError("user名 long 度必须 in 3-20个字符之间")
if not username.isalnum():
raise FormatError("user名只能package含字母 and number")
return True
def validate_email(email):
"""
verification邮箱
Args:
email: 邮箱地址
Returns:
bool: verification is 否成功
Raises:
EmptyInputError: such as果邮箱 for 空
FormatError: such as果邮箱格式不符合要求
"""
if not email:
raise EmptyInputError("邮箱不能 for 空")
if '@' not in email or '.' not in email:
raise FormatError("邮箱格式不正确")
return True
def validate_age(age):
"""
verification年龄
Args:
age: 年龄
Returns:
bool: verification is 否成功
Raises:
EmptyInputError: such as果年龄 for 空
FormatError: such as果年龄不 is number
ValueErro: such as果年龄不 in has 效范围 in
"""
if not age:
raise EmptyInputError("年龄不能 for 空")
try:
age_int = int(age)
except ValueError:
raise FormatError("年龄必须 is number")
if age_int < 0 or age_int > 150:
raise ValueError("年龄必须 in 0-150之间")
return True
def register_user():
"""registeruser"""
print("=== userregister ===")
while True:
try:
username = input("请输入user名: ")
validate_username(username)
break
except InputValidationError as e:
print(f"error: {e}")
while True:
try:
email = input("请输入邮箱: ")
validate_email(email)
break
except InputValidationError as e:
print(f"error: {e}")
while True:
try:
age = input("请输入年龄: ")
validate_age(age)
break
except (InputValidationError, ValueError) as e:
print(f"error: {e}")
print("\nregister成功!")
print(f"user名: {username}")
print(f"邮箱: {email}")
print(f"年龄: {age}")
# testuserregister
if __name__ == "__main__":
register_user()
creation一个function, 接收两个numberserving asparameter, 返回它们 商. usingexceptionprocessing来processing可能 error, such as除零error and class型error.
def safe_divide(a, b):
"""
security地计算两个数 商
Args:
a: 被除数
b: 除数
Returns:
float: 商
Raises:
ValueError: such as果输入不 is number
ZeroDivisionError: such as果除数 for 零
"""
# implementation你 code
pass
# testfunction
test_cases = [
(10, 2),
(5, 0),
("10", 2),
(10, "2"),
("10", "2"),
]
for a, b in test_cases:
try:
result = safe_divide(a, b)
print(f"{a} / {b} = {result}")
except Exception as e:
print(f"{a} / {b} error: {e}")
creation一个function, 读取file in 容并返回. usingexceptionprocessing来processing可能 fileoperationerror, such asfile未找 to error and permissionerror.
def read_file(file_path):
"""
读取file in 容
Args:
file_path: filepath
Returns:
str: file in 容
Raises:
Exception: such as果file读取失败
"""
# implementation你 code
pass
# testfunction
test_files = [
"example.txt",
"nonexistent_file.txt",
]
for file_path in test_files:
try:
content = read_file(file_path)
print(f"file '{file_path}' 读取成功:")
print(content)
except Exception as e:
print(f"file '{file_path}' 读取失败: {e}")
creation一个银行accountclass, using自定义exceptionclass来processing各种accountoperationerror, such as余额不足, 无效金额etc..
# creation自定义exceptionclass
class BankAccountError(Exception):
"""银行accountexception"""
pass
class InsufficientFundsError(BankAccountError):
"""余额不足exception"""
pass
class InvalidAmountError(BankAccountError):
"""无效金额exception"""
pass
class BankAccount:
"""银行accountclass"""
def __init__(self, balance=0):
self.balance = balance
def deposit(self, amount):
"""
存款
Args:
amount: 存款金额
Raises:
InvalidAmountError: such as果金额无效
"""
# implementation你 code
pass
def withdraw(self, amount):
"""
取款
Args:
amount: 取款金额
Raises:
InvalidAmountError: such as果金额无效
InsufficientFundsError: such as果余额不足
"""
# implementation你 code
pass
def get_balance(self):
"""
获取余额
Returns:
float: account余额
"""
return self.balance
# test银行account
account = BankAccount(1000)
print(f"初始余额: {account.get_balance()}")
try:
account.deposit(500)
print(f"存款 after 余额: {account.get_balance()}")
except BankAccountError as e:
print(f"存款error: {e}")
try:
account.withdraw(200)
print(f"取款 after 余额: {account.get_balance()}")
except BankAccountError as e:
print(f"取款error: {e}")
try:
account.withdraw(2000)
print(f"取款 after 余额: {account.get_balance()}")
except BankAccountError as e:
print(f"取款error: {e}")
try:
account.deposit(-100)
print(f"存款 after 余额: {account.get_balance()}")
except BankAccountError as e:
print(f"存款error: {e}")