Day03 AI智能体筑基打卡

当 Python 首次登顶 TIOBE 榜首、取代霸榜多年的 Java,AI 时代的编程版图已然改写。语法易学只是入场券,真正的分水岭在于智能体应用开发中的落地能力。无论你是在校园里学着与现实脱节的旧知识,还是身处传统前后端领域面临被替代的焦虑——这个系列不绕弯子、不讲废话,只聚焦那些真正会卡住你的痛点,记录一步步踩坑与补全认知的过程。

AI 浪潮下,我们都是摸着石头过河的同行者。与其被焦虑裹挟,不如把学习日常摊开来,一起查缺补漏、扎实成长。希望这些记录能陪你在这场技术变革中,走得更稳、更远。

核心目标:用类封装关联功能,为后续 RAG/Agent 类打基础。

一、今日学习内容

类与实例、构造函数__init__

:描述一组具有相同属性和方法的模板。(图纸,没有实体)

实例(对象):是基于类创建出来的,有属性方法,创建对象的过程也叫对象的实例化。(产品,有实体,可以有无数个)

__init__:构造方法,基于类创建对象的时候,会自动调用此方法。(根据图纸造产品的方法,自动调用)

属性:属于对象的变量。

方法:属于对象的方法,定义语法与函数一致。

class Dog:
    # 构造函数:造实例时自动触发,self=当前实例
    def __init__(self, name, age):
        self.name = name  # 绑定属性
        self.age = age

    # 普通方法
    def bark(self):
        print(f"{self.name} 叫了一声,{self.age}岁")

# 造实例(触发 __init__)
dog1 = Dog("旺财", 3)
dog2 = Dog("小黑", 5)

# 调用
dog1.bark()  # 旺财 叫了一声,3岁
dog2.bark()  # 小黑 叫了一声,5岁

注:一个类可以创建无数个对象,self是必传参数,表示当前创建的实例对象(是对象再类中的代表)。

注:类名的命名规范,遵循大驼峰命名法。

私有属性、封装原则、对外接口设计(黑匣子原理)

私有属性:私有的属性和方法只能在类的内部使用; Python中并没有真正的私有机制,约定在私有属性名和方法名前加__(两个下划线)。

封装:将数据(属性)及操作数据的方法绑定在同一个类结构中,对外隐藏内部实现细节,仅暴露必要的公共接口供外部访问。

对外接口:外部想要调用封装的方法或数据,只能通过类的对外接口调用。

class BankAccount:
    def __init__(self, balance):
        self.__balance = balance  # 私有属性(双下划线,外面动不了)

    def deposit(self, amount):    # 对外接口1:存钱
        if amount > 0:
            self.__balance += amount

    def get_balance(self):        # 对外接口2:查余额(只读,不能改)
        return self.__balance     # 大部分读取私有属性都会用get方法

# 使用
acc = BankAccount(1000)
acc.deposit(500)                 # 通过接口存钱
print(acc.get_balance())         # 通过接口查余额:1500
print(acc.__balance)             # 报错!直接访问私有属性,外面碰不到

为什么要封装:封装将数据(属性)和操作数据的方法捆绑为独立单元,通过隐藏内部实现细节、仅暴露公共接口,达到隔离变化、保护数据完整性、降低耦合的目的。外部不关心内部怎么算的,只管调用接口就行,内部改动不影响外部调用代码。

单一职责类设计方法

和单一职责函数一样,一个萝卜一个坑。

核心思想:一个类,只干且必须干好一件事。

特点:单一职责写出来的类,一看类名就知道是做什么的,通常也很短,用起来方便,保证代码逻辑清晰,低耦合,十分的优雅。

二、今日核心代码

"""
文件工具类:支持 TXT/MD 读取、JSON 写入
参考开源项目的文件操作封装模式
"""
from pathlib import Path  # 导入Path类,用于跨平台路径操作
from typing import Optional  # 导入Optional类型提示(实际未使用)
from .exceptions import FileOperateException  # 导入自定义文件操作异常类


class FileUtil:
    """文件读写、路径处理工具,基于pathlib,跨平台兼容"""

    @staticmethod  # 装饰器,声明一个静态方法
    def get_project_root() -> Path:
        """获取项目根目录"""
        return Path(__file__).parent.parent

    @staticmethod
    def safe_read(file_path: str | Path, encoding: str = "utf‑8") -> str:
        """安全读取文本文件"""
        fp = Path(file_path)  # 转换为Path对象,统一处理
        if not fp.exists():  # 检查路径是否纯在
            raise FileOperateException(message=f"文件不存在:{fp}")  # 抛异常
        if not fp.is_file():  # 检查是否为普通文件
            raise FileOperateException(message=f"不是合法文件:{fp}")  # 继续抛异常
        try:
            return fp.read_text(encoding=encoding)  # 读取全部文件内容
        except Exception as e:  # 捕获所有异常(兜底)
            raise FileOperateException(message=f"读取失败:{str(e)}") from e  # 还是抛出异常

    @staticmethod
    def safe_write(file_path: str | Path, content: str, encoding: str = "utf‑8") -> None:
        """写入文件,不存在自动创建父目录"""
        fp = Path(file_path)
        fp.parent.mkdir(parents=True, exist_ok=True)  # 父目录不存在则递归创建
        try:
            fp.write_text(content, encoding=encoding)  # 写入文本
        except Exception as e:
            raise FileOperateException(message=f"写入失败:{str(e)}") from e

    @staticmethod
    def safe_append(file_path: str | Path, content: str, encoding: str = "utf‑8") -> None:
        """追加写入"""
        fp = Path(file_path)
        fp.parent.mkdir(parents=True, exist_ok=True)
        old = ""
        if fp.exists():
            old = fp.read_text(encoding=encoding)
        FileUtil.safe_write(fp, old + content, encoding=encoding)  # 将新旧内容整体写入

三、每日三件事

  1. 今日代码实操完成情况: 完成文件工具 + 配置工具,跑通读写测试

  2. 今日踩坑Bug+原因+解决方案:

    程序在 PyCharm 点击运行正常;在终端命令行运行直接报文件不存在

    # 错误写法,写死相对字符串
    fp = Path("./data/test.txt")
    

    PyCharm 默认工作目录是项目根目录;终端 cd 到别的目录执行脚本,工作目录就变了,./指向就错,直接抛FileOperateException

    # 正确写法
    @staticmethod
    def get_project_root() -> Path:
        # 根据当前file_utils.py文件位置向上找根目录,不受运行目录影响
        return Path(__file__).parent.parent
    

    面试可以这么说:

    “做文件工具封装时踩过相对路径大坑,直接写./依赖运行时工作目录,终端运行就失效。我用__file__拿到 py 文件真实位置,向上推导项目根目录,所有路径基于根目录拼接,彻底隔离运行目录差异。

    同时统一处理父目录自动创建、强制 utf‑8 编码、区分文件与文件夹判断,把这些重复逻辑封装进 file_utils,上层业务代码只调用工具方法,不用关心底层文件细节。”

  3. GitHub当日代码仓库地址: https://github.com/Youlan514/AI_Agent_Basic

四、今日优质代码习惯

一个顶级原则:越早暴露错误,调试成本越低(快失败Fail Fast)。

  • 坏习惯:返回 NoneFalse 让调用方去猜。
  • 好习惯条件不满足直接 raise。让异常穿透到最外层统一处理,避免错误数据在代码里“游荡”。

更多推荐