Python青少年简明教程:异常

Python青少年简明教程:异常

异常处理是 Python 程序开发中不可或缺的一部分。通过合理地使用异常处理机制,可以提高程序的健壮性和可靠性,并提供更友好的用户体验。

异常(Exception)是指在程序执行过程中出现的错误或意外情况。例如常见内置异常:

ZeroDivisionError: 当尝试除以 0 时发生。

TypeError: 当操作数类型不匹配时发生。

当发生异常时,程序会中断执行,并将控制权转移到异常处理代码,以便对异常进行捕获和处理。异常可以分为两类:内建异常(built-in exceptions)和自定义异常(custom exceptions)。

内建异常:Python提供的一组预定义异常类型,如ZeroDivisionError、IndexError、KeyError等,用于表示程序执行过程中可能遇到的各种错误情况。

自定义异常:根据特定需求创建的用户自定义的异常类型,用于表示程序中特有的错误情况。

try-except语句

Python中使用try-except语句来处理异常。基本语法结构如下:

try:
    # 可能引发异常的代码
except 异常类型:
    # 处理特定类型异常的代码
[except:
    #处理所有其他异常(不建议这样做)]
[else:
    # 没有异常时执行的代码]
[finally:
    # 无论是否有异常都会执行的代码]

说明:

try子句:包含可能引发异常的代码。

except子句:用于捕获并处理异常。可以指定要捕获的异常类型,并定义处理异常的代码。可以有多个except子句来处理不同类型的异常。Python 提供了许多内置的异常类型。

else子句(可选):如果没有发生任何异常,则执行else子句中的代码。

finally子句(可选):无论是否发生异常,finally子句中的代码都会执行。通常用于清理工作,如关闭文件或释放资源。

[]部分代表可选。

Python 有许多内置的异常类型,它们都继承自基类 Exception。以下是一些常见的异常类型及其说明:

☆ SyntaxError: 语法错误。当Python解释器遇到无效的语法时引发此异常。
eval('x===1')  # 语法错误

☆ IndentationError: 缩进错误;在程序中使用错误的缩进。
def func():
print("Hello")  # IndentationError

☆ TypeError: 类型错误;发生在操作或函数应用于不兼容的类型时。

age_str = input("请输入你的年龄: ")  
try:  
    age = int(age_str)  
    print(f"你的年龄是 {age} 岁。")  
except ValueError:  
print("输入的不是一个有效的整数!")

☆ ValueError: 值错误;当一个操作或函数接收到参数类型正确但值不正确的情况。
int('abc')  # ValueError

☆ IndexError: 索引错误;访问的序列索引超出范围。

try:
    # 可能引发 IndexError
    list_example = [1, 2, 3]
    print(list_example[10])
except IndexError:
    print("列表索引超出范围")

☆ KeyError: 键错误;在字典中访问不存在的键时引发。

try:
    # 可能引发 KeyError
    dict_example = {"a": 1, "b": 2}
    print(dict_example["c"])
except KeyError:
    print("字典中不存在该键")

☆ AttributeError: 属性错误;访问对象没有的属性时引发。

class MyClass:
    pass

obj = MyClass()
print(obj.attr)  # AttributeError

☆ ZeroDivisionError: 除零错误;尝试用零除。
result = 1 / 0  # ZeroDivisionError

☆ ImportError: 导入错误;当尝试导入不存在的模块或模块中的名称时引发。
import non_existent_module  # ImportError

☆ 在 Python 3 中,推荐使用 OSError 及其更具体的子类(如 FileNotFoundError, )来处理文件和 I/O 相关的异常。
早期的IOError 在 Python 3 中仍然存在,但实际上是 OSError 的别名,主要是为了向后兼容。

try:
    with open("non_existent_file.txt", "r") as file:
        content = file.read()
except FileNotFoundError:
    print("文件不存在")

限制输入是一种常见且有效的编程技巧。这种方法可以帮助你确保用户输入的数据符合预期,并优雅地处理不符合要求的输入。下面给出使用异常处理限制输入示例。

例1、要求:限制输入一个 0到 100 之间的正整数(不能带小数),否则提示重新输入,直到符合要求。源码如下:

while True:
    try:
        n = int(input("请输入一个 0 到 100之间的正整数(不能带小数):"))
        if 0<=n<=100:
            print("输入正确") 
            break
        else:
            print("输入的正整数不在 0 到 100之间,请重新输入")    
    except:
        print("输入的不是正整数,请重新输入")

修改上面代码,采用Tkinter界面,按回车键或点击“提交”按钮进行限制检测,源码如下:

import tkinter as tk
from tkinter import messagebox

def validate_input(event=None):
    try:
        n = int(entry.get())
        if 0 <= n <= 100:
            messagebox.showinfo("结果", "输入正确")
            root.quit()
        else:
            messagebox.showerror("错误", "输入的正整数不在 0 到 100之间,请重新输入")
    except ValueError:
        messagebox.showerror("错误", "输入的不是正整数,请重新输入")

root = tk.Tk()
root.title("整数输入验证")
root.geometry("300x100")

label = tk.Label(root, text="请输入一个 0 到 100之间的正整数(不能带小数):")
label.pack()

entry = tk.Entry(root)
entry.pack()
entry.bind('<Return>', validate_input)  # 绑定回车键事件

button = tk.Button(root, text="提交", command=validate_input)
button.pack()

root.mainloop()

例2、要求:限制输入一个 0到 100 之间的数值(可带小数),否则提示重新输入,直到符合要求。源码如下:

while True:
    try:
        num = float(input("请输入一个 0 到 100之间的数值(可带小数):"))
        if 0 <= num <= 100.00:
            print("输入正确")
            break
        else:
            print("输入的数值不在 0 到 100 之间,请重新输入")
    except ValueError:
        print("输入的不是数值,请重新输入")

修改上面代码,采用Tkinter界面实现,按回车键或点击“提交”按钮进行限制检测,源码如下:

import tkinter as tk
from tkinter import messagebox

def validate_input(event=None):
    try:
        num = float(entry.get())
        if 0 <= num <= 100.00:
            messagebox.showinfo("结果", "输入正确")
            root.quit()
        else:
            messagebox.showerror("错误", "输入的数值不在 0 到 100 之间,请重新输入")
    except ValueError:
        messagebox.showerror("错误", "输入的不是数值,请重新输入")

root = tk.Tk()
root.title("浮点数输入验证")
root.geometry("300x100")

label = tk.Label(root, text="请输入一个 0 到 100之间的数值(可带小数):")
label.pack()

entry = tk.Entry(root)
entry.pack()
entry.bind('<Return>', validate_input)  # 绑定回车键事件

button = tk.Button(root, text="提交", command=validate_input)
button.pack()

root.mainloop()

例3、限制日期输入:

from datetime import datetime

while True:
    try:
        date_str = input("请输入日期(YYYY-MM-DD):")
        date = datetime.strptime(date_str, "%Y-%m-%d")
        break
    except ValueError:
        print("无效的日期格式,请使用YYYY-MM-DD格式")

关键字as

关键字as用在 except 子句中,允许你将捕获到的异常对象赋值给一个变量以便后续使用。基本语法:

try:
    # 可能引发异常的代码
except ExceptionType as exception_variable:
    # 使用 exception_variable 处理异常

示例:

try:
    # 可能会引发异常的代码块
    result = 10 / 0
except ZeroDivisionError as e:
    print("捕获到异常:", e)
    print("异常类型:", type(e))
    print("错误信息:", e.args)

在这个例子中,as e 将 ZeroDivisionError 异常对象赋值给变量 e,然后可以使用 e 访问异常对象的属性,例如 type(e) 获取异常类型,e.args 获取错误信息。

输出:

捕获到异常: division by zero
异常类型: <class 'ZeroDivisionError'>
错误信息: ('division by zero',)

又如:

try:
    file = open("non_existent_file.txt", "r")
except FileNotFoundError as e:
    print(f"文件未找到: {e.filename}")
    print(f"错误信息: {str(e)}")

若当前目录中不存在non_existent_file.tx,将输出:

文件未找到: non_existent_file.txt
错误信息: [Errno 2] No such file or directory: 'non_existent_file.txt'

在这个例子中:

e 是捕获到的 FileNotFoundError 异常的实例。

e.filename 访问异常对象的 filename 属性,获取未找到的文件名。

str(e) 获取异常的字符串描述。

抛出异常

raise 关键字用于主动抛出(引发)一个异常。这允许程序员在特定条件下强制触发一个异常,而不是等待 Python 解释器自动检测到错误。基本语法:

raise ExceptionType("错误信息")

其中,ExceptionType 并不是 Python 中的一个具体异常类型,而是一个泛指。它代表任何 Python 内置的(内置的异常类型见前面)或用户自定义的异常。

示例:

try:
    x = int(input("输入一个正数: "))
    if x <= 0:
        raise ValueError("输入必须为正数")
except ValueError as e:
    print(f"错误: {e}")

自定义异常

在 Python 中,自定义异常通常需要使用类来定义。在未学习类之前,不必深究,了解即可。

在Python中自定义异常通常是通过创建新的类来实现的。基本格式如下:

class MyCustomError(Exception):
    """自定义异常类"""
    pass

try:
    # 触发自定义异常
    raise MyCustomError("自定义错误信息")
except MyCustomError as e:
    print("捕获到自定义异常:", e)
 

下面是一个完整的自定义异常的示例:

class MyCustomException(Exception):
    def __init__(self, message):
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        return f"MyCustomException: {self.message}"

def divide(a, b):
    if b == 0:
        raise MyCustomException("除数不能为零!")
    return a / b

try:
    result = divide(10, 0)
except MyCustomException as e:
    print("捕获到自定义异常:", e)

 

在这个示例中,我们定义了一个名为 MyCustomException 的自定义异常类,它继承自内置的 Exception 类。我们在 MyCustomException 类的构造方法中接收一个 message 参数,表示异常的错误信息。通过调用 super().__init__(self.message),我们将错误信息传递给父类的构造方法。

在 divide 函数中,我们通过 raise MyCustomException("除数不能为零!") 主动抛出了自定义异常。当程序执行到这一行时,会触发异常,然后跳转到 except MyCustomException as e 的代码块中。在 except 块中,我们可以通过变量 e 访问到捕获到的自定义异常对象,并打印出错误信息:

捕获到自定义异常: MyCustomException: 除数不能为零!

附、Python异常处理 https://blog.csdn.net/cnds123/article/details/108530930

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习&实践爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值