Python入门⑤-异常处理、文件操作与实战项目

本系列文章将带你从零开始学习Python,从环境搭建到实战项目,一步步掌握Python编程的核心知识。这是系列收官篇,我们将学习异常处理、文件操作和程序测试,最后通过一个完整的实战项目来综合运用前面学到的所有知识。

📖 系列专栏一文入门Python------Agent基础课(点击可查看全部文章)


目录

一、异常处理

程序运行过程中难免会遇到错误,Python通过异常处理机制让程序能够优雅地处理错误,而不是直接崩溃:

python 复制代码
try:
    num = int(input("请输入一个数字:"))
    result = 10 / num                               #有可能有错误的部分
    print(f"10除以{num}的结果是:{result}")
except ValueError:                                  #产生值错误
    print("输入的不是有效数字!")
except ZeroDivisionError:                           #产生除0错误
    print("不能除以零!")
except Exception as e:                              #产生了错误`e`
    print(f"发生了未知错误:{e}")
else:
    print("没有发生任何错误!")
finally:
    print("无论是否出错,都会执行这一行")
python 复制代码
try:
	num = int(input("请输入一个数字:"))
    result = 10 / num
    print(f"10除以{num}的结果是:{result}")
except:                                             #产生了错误,不知道具体的
	print("产生了错误)

try-except结构可以捕获并处理特定类型的异常,else块在没有异常时执行,finally块则保证无论是否出错都会执行。合理使用异常处理能让你的程序更加健壮和用户友好。


二、文件操作

2.1 绝对路径和相对路径

  • 绝对路径是从磁盘根目录(如C:\/)开始的完整路径,例如C:\Users\张三\Documents\file.txt
  • 相对路径是相对于当前工作目录的路径,例如data\file.txt表示当前目录下的data文件夹中的文件,.\task.txt 就是当前文件下的task.txt,.\可以省略。
函数/方法 作用说明 使用示例
os.path.abspath(path) 将相对路径转换为绝对路径 os.path.abspath("./poem.txt")
os.path.dirname(path) 获取文件所在的目录路径 os.path.dirname(__file__) → 当前脚本的文件夹路径
os.path.basename(path) 获取路径中的文件名部分 os.path.basename("/a/b/poem.txt") → 返回 "poem.txt"
os.path.join(path, *paths) 智能拼接多个路径片段,自动适配不同系统的分隔符 os.path.join(os.path.dirname(__file__), "poem.txt")
os.path.exists(path) 判断路径(文件/文件夹)是否存在,返回布尔值 if os.path.exists("./poem.txt"):
os.path.isfile(path) 判断路径是否为一个文件 os.path.isfile("./poem.txt")True
os.path.isdir(path) 判断路径是否为一个文件夹 os.path.isdir("./data")True(如果存在)
os.path.splitext(path) 分割文件名和扩展名,返回元组 (文件名, 后缀) os.path.splitext("poem.txt")("poem", ".txt")
os.path.getsize(path) 获取文件大小,单位是字节 os.path.getsize("poem.txt")

2.2 文件操作

文件操作是编程中非常常见的需求,Python提供了简洁的文件操作接口。使用open()函数可以打开文件,并指定模式进行读写:

python 复制代码
# 写入文件
with open("hello.txt", "w", encoding="utf-8") as f:
    f.write("你好,世界!")

# 读取文件
with open("hello.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print(content)  # 输出:你好,世界!

with语句会自动管理文件的打开和关闭,即使发生异常也能正确关闭文件。常见的文件模式包括:

  • r(读取,不存在会报错),可以使用r+ 既可以读又可以写
  • w(写入,会覆盖原有内容,不存在不报错会新创建一个),w+:可读可写
  • a(追加写入,不存在不报错会新创建一个),a+:可读可追加
  • rb(二进制读取)等。

三、程序测试

编写完代码后,测试是确保程序正确运行的重要环节。Python提供了多种测试方式,从简单的print调试到使用unittest模块编写自动化测试:

通常我们会新建一个测试文件来区分任务代码和测试代码

3.1 简单测试

最简单的测试方式是使用 print 输出结果,用人眼判断是否正确。这种方式直接高效,适合快速验证:

python 复制代码
def add(a, b):
    return a + b

# 简单测试
print(add(2, 3))       # 手动看输出是不是 5
print(add(-1, 1))      # 手动看输出是不是 0
print(add(0, 0))       # 手动看输出是不是 0

除了用 print,Python 内置了 assert(断言)语句来自动检查条件是否成立。如果条件为 True 则什么也不发生,反之会抛出 AssertionError

python 复制代码
def add(a, b):
    return a + b

# 使用 assert 进行自动验证
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
print("所有简单测试通过!")

assert 还可以附带错误信息,方便定位问题:

python 复制代码
assert add(2, 3) == 5, f"期望 5,但得到了 {add(2, 3)}"

适用场景 :脚本或小型功能用 print / assert 快速验证即可,但项目变大后维护成本高(没人会逐行看输出)。

3.2 unittest测试

Python 内置了 unittest 模块,提供了专业的自动化测试框架。相比 print + assertunittest 的优势在于:可以批量运行测试、自动报告测试结果、支持测试夹具(setUp/tearDown)等。

基本结构 :新建一个测试文件(如 test_calculator.py),创建一个继承 unittest.TestCase 的测试类,类中的每个方法(要求以 test_ 开头)就是一个测试用例:

python 复制代码
import unittest
from calculator import add  # 假设要测试的函数在 calculator.py 中

class TestCalculator(unittest.TestCase):
    """测试计算器模块"""

    def test_add_positive(self):
        """测试正数相加"""
        self.assertEqual(add(2, 3), 5)

    def test_add_negative(self):
        """测试负数相加"""
        self.assertEqual(add(-1, 1), 0)

    def test_add_zero(self):
        """测试加零"""
        self.assertEqual(add(0, 0), 0)

    def test_add_large(self):
        """测试大数相加"""
        self.assertEqual(add(999999, 1), 1000000)

if __name__ == "__main__":
    unittest.main()

常用断言方法

断言方法 作用
assertEqual(a, b) 检查 a == b
assertNotEqual(a, b) 检查 a != b
assertTrue(x) 检查 x 为真
assertFalse(x) 检查 x 为假
assertIsNone(x) 检查 xNone
assertIsNotNone(x) 检查 x 不为 None
assertIn(a, b) 检查 a in b
assertNotIn(a, b) 检查 a not in b
assertRaises(异常类型, 函数, 参数) 检查是否抛出指定异常

使用 assertRaises 测试异常

python 复制代码
def divide(a, b):
    if b == 0:
        raise ValueError("除数不能为零")
    return a / b

class TestDivide(unittest.TestCase):
    def test_divide_by_zero(self):
        """测试除零异常"""
        with self.assertRaises(ValueError):
            divide(10, 0)

使用 setUp 和 tearDown 准备测试环境

python 复制代码
import tempfile
import os

class TestFileOps(unittest.TestCase):
    def setUp(self):
        """每个测试方法运行前执行,用于创建测试环境"""
        self.test_dir = tempfile.mkdtemp()
        self.test_file = os.path.join(self.test_dir, "test.txt")
        with open(self.test_file, "w", encoding="utf-8") as f:
            f.write("Hello, World!")

    def tearDown(self):
        """每个测试方法运行后执行,用于清理测试环境"""
        import shutil
        shutil.rmtree(self.test_dir)

    def test_read_file(self):
        with open(self.test_file, "r", encoding="utf-8") as f:
            content = f.read()
        self.assertEqual(content, "Hello, World!")

运行测试的方式

  1. 命令行运行 :在终端执行python -m unittest(测试所有测试类,自动搜索所有继承unittest.TestCase的类) 或python -m unittest test_calculator.py
  2. 命令行详细模式python -m unittest -v test_calculator.py(带详细信息)
  3. 直接在 PyCharm 中:点击测试方法或测试类旁边的绿色三角按钮运行

运行后会看到清晰的测试结果报告(.表示通过,F表示失败,E表示出错)。

最佳实践建议 :一个函数对应一个测试类,一个函数功能分支对应一个测试方法。保持测试的独立性------每个测试方法之间互不依赖。setUptearDown 会在每个测试方法执行前后都运行一次,非常适合准备隔离的测试环境。


四、实战:构建一个简单的命令行待办事项管理器

将前面学到的知识综合运用,我们来创建一个实用的待办事项管理器。这个程序将使用函数组织代码、列表存储数据、文件操作保存任务、异常处理应对错误输入:

python 复制代码
import json
import os

TODO_FILE = ".\tasks.json"

def load_tasks():
    if not os.path.exists(TODO_FILE):
        return []
    with open(TODO_FILE, "r", encoding="utf-8") as f:
        return json.load(f)

def save_tasks(tasks):
    with open(TODO_FILE, "w", encoding="utf-8") as f:
        json.dump(tasks, f, ensure_ascii=False, indent=2)

def add_task(tasks):
    title = input("请输入任务名称:")
    tasks.append({"title": title, "done": False})
    print(f"已添加任务:{title}")

def list_tasks(tasks):
    if not tasks:
        print("暂无任务")
        return
    for i, task in enumerate(tasks, 1):
        status = "✓" if task["done"] else "✗"
        print(f"{i}. [{status}] {task['title']}")

def main():
    tasks = load_tasks()
    while True:
        print("\n1. 添加任务  2. 查看任务  3. 退出")
        choice = input("请选择操作:")
        if choice == "1":
            add_task(tasks)
            save_tasks(tasks)
        elif choice == "2":
            list_tasks(tasks)
        elif choice == "3":
            print("再见!")
            break
        else:
            print("无效输入,请重新选择")

if __name__ == "__main__":
    main()

这个程序展示了函数定义、列表操作、文件读写、异常处理(输入验证)和模块导入的综合应用。运行后,你的任务会自动保存到本地文件,下次启动时自动加载。


结语

当你看到这里,恭喜你已经完成了Python基础语法的学习之旅!从变量、数据类型、控制流到函数、文件操作、异常处理和单元测试,你已掌握了用Python解决实际问题所需的核心知识。接下来可以尝试自己编写一些小项目,比如爬虫、数据分析脚本或简单的Web应用,在实践中巩固所学。记住,编程是一门动手的技能,多写多练是进步的关键。


📖 系列专栏一文入门Python------Agent基础课

感谢你的阅读!如果觉得有帮助,欢迎 点赞、收藏、关注 三连支持,后续会持续更新更多实用内容!

相关推荐
吴声子夜歌1 小时前
MongoDB 4.x——SpringBoot框架整合
数据库·spring boot·mongodb
LONGZETECH1 小时前
新能源汽车充电设备装配与调试仿真教学软件 技术架构与核心实现解析
大数据·算法·3d·unity·架构·汽车
卷无止境1 小时前
提升 Python 代码健壮性的方法大盘点
后端·python
自学小白菜1 小时前
关于提升机器学习算法做预测回归任务精度的方法分享
算法·机器学习·回归·提升精度
asdzx671 小时前
Python PDF 拆分实战指南:单页拆分与按需页码范围拆分
开发语言·python·pdf
LadenKiller1 小时前
近期AI训练量化表达,解释改写检查要按顺序
人工智能·python
李昊哲小课1 小时前
咖啡工坊 · FastAPI 22 章教程合集
服务器·人工智能·python·fastapi
学废了wuwu1 小时前
从入门到实战:深入浅出模型压缩三大核心——剪枝、彩票假设与知识蒸馏
人工智能·算法·剪枝
孬甭_1 小时前
C++ vector
开发语言·c++