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基础课

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

相关推荐
奇特認11 分钟前
mysql 集群技术 3.高可用之 MHA
数据库·mysql
油丶酸萝卜别吃12 分钟前
utils.js 说明文档
开发语言·javascript·ecmascript
rannn_1113 小时前
【力扣hot100】链表专题|160、206、234、141、142
java·算法·leetcode·链表·面试·开发
Bioinfo Guy3 小时前
高分Panel复现系列|转录因子网络太乱?用模块框把重点圈出来
数据库·生物信息学·生信可视化
数模竞赛Paid answer3 小时前
2026年华东杯数学建模B题医药物流安排问题解题全过程文档及程序
算法·数学建模·数据分析·华东杯
leisoo80973 小时前
100GBA股股票数据怎么存ClickHouseRedisMySQLJSON完整对比
大数据·linux·服务器·开发语言·python
WangYan20223 小时前
基于XGBoost与AI的生态—地学多源数据建模:植被与土地利用识别、土壤碳氮空间预测、生物多样性驱动机制、土壤微生物功能预测、生态退化与风险识别
python·机器学习·xgboost
不会代码的小猴4 小时前
21. 泛型编程上
开发语言·c++·笔记·算法
ltl4 小时前
Disaggregated DB 合集:Socrates、PolarDB、Taurus 的共同模式
数据库
AI备案指南-满满4 小时前
大模型与算法备案全流程详解:从零到通过的完整指南
人工智能·算法·备案·大模型备案·算法备案