Day 05 / 共 68 天 · 阶段 1 编程地基

Python 极速入门③

昨天(Day 04)学了函数和数据结构。今天补齐语法最后一块:用 class 把"数据+功能"捆成对象、用 import 借别人写好的模块、用 try/except 接住报错不让程序崩,再学会用虚拟环境给每个项目开一间"独立车间"。学完你就能看懂真实 AI 项目的代码结构;明天(Day 06)转战命令行和 Git。

📍 你在阶段 1(编程地基 D3-9)的位置
D03 Python① D04 Python② D05 Python③ D06 命令行&Git D07 调 API
💡 用一个类比兜住今天(今天全程沿用「一座工厂」的世界观) 写程序 = 经营一座工厂class 类 = 一张图纸/模具(定义"机器人长啥样、能干啥");object 对象 = 按图纸造出来的一台台实物;属性 = 产品的参数(型号、电量),方法 = 产品自带的按钮(按一下就干活);import = 从供应商进现成零件(不用自己造轮子);try/except = 产线上的安全网(零件坏了不炸整条线);虚拟环境 venv = 每条产线一间独立车间,原料互不串味。今天你从"操作工"升级成"车间主任"。
L01

类 class:一张造物图纸

🤔 痛点Day04 用字典存一个用户 {"name":..., "age":...}。可如果每个用户还要能"打招呼""升级会员",数据和操作它们的函数散落各处,越写越乱。
💡 本质就是把"一类东西的数据 + 能对它做的操作"打包成一张图纸;按图纸造出的具体一个个实物叫对象。像"机器人图纸"造出"机器人1号、2号",每台都有自己的电量,也都会同一套动作。
class Robot:                          # 定义一张"机器人图纸"(类名习惯大写开头)
    def __init__(self, name):         # __init__ 是"出厂初始化",造它时自动跑
        self.name = name              # self 指"这一台自己";给它记上名字
        self.battery = 100            # 每台出厂电量 100

# 按图纸造两台实物(对象)——像调用函数一样,传入名字
r1 = Robot("小白")
r2 = Robot("小黑")
print(r1.name, r1.battery)           # 用 . 取它的属性 → 小白 100
print(r2.name)                       # → 小黑(两台互不影响,各是各的)
👶 self 到底是啥?self 就是"这一台机器人自己"。图纸是死的,但造出来每台各有各的名字和电量,self 就是用来指"当前正在操作的这一台"。写方法时第一个参数永远写 self(照抄就行),调用时不用你传,Python 自动填。现在记不牢没关系,混脸熟即可。
L02

属性 & 方法:产品的参数和按钮

🤔 痛点光有数据不够,机器人得能"干活"——走路会耗电、能报告状态。这些"动作"写哪?
💡 本质写进类里的函数叫方法(product 自带的按钮),它能读写自己的属性(参数)。对象.属性 取数据,对象.方法() 让它干活。
class Robot:
    def __init__(self, name):
        self.name = name
        self.battery = 100

    def walk(self):                   # 一个方法(按钮):走一步耗 10 电
        self.battery = self.battery - 10
        print(f"{self.name} 走了一步,剩余电量 {self.battery}")

    def report(self):                 # 另一个方法:报告状态
        return f"{self.name}:电量 {self.battery}%"

r = Robot("小白")
r.walk()                 # 按"走路"按钮 → 小白 走了一步,剩余电量 90
r.walk()                 # → 小白 走了一步,剩余电量 80
print(r.report())        # → 小白:电量 80%
一张图纸(class) → 造出多个对象,各自独立 图纸 Robot 属性:name,battery|方法:walk,report 对象 r1「小白」 battery=80 对象 r2「小黑」 battery=100
图注:图纸只写一次,造出的每个对象各有各的状态(小白走过路电量 80,小黑还是 100)。
📝 举个例子:真实 AI 代码里到处是类 以后你会写 client = OpenAI()agent = Agent(...)——这就是"按图纸造对象"。然后 client.chat(...)agent.run(...) 就是"按对象的按钮(方法)"。你现在能看懂 对象.方法() 这种写法,就已经能读懂大半 AI 库的示例代码了。
心态提示:类是本阶段最抽象的一块。你现在的目标不是"能熟练设计类",而是"看到别人的类代码能读懂"——认得出属性、方法、对象.xxx 就够。会用 > 会造,后面自然熟。
L03

import:从供应商进现成零件

🤔 痛点要算平方根、取随机数、处理日期……难道全自己写?工厂不会自己造每一颗螺丝。
💡 本质import 就是"进货":把 Python 自带的或 pip 装来的模块(现成零件包)拿进来用。写一句 import 模块名,里面所有工具就归你调。
# 方式1:整包进货,用"模块名.工具"调用
import random                    # random = 随机模块(Python 自带)
print(random.randint(1, 6))      # 掷骰子:1~6 随机一个数

import math
print(math.sqrt(16))             # 平方根 → 4.0

# 方式2:只进货包里的某个工具(更常用)
from datetime import datetime    # 从 datetime 包只拿 datetime 这个工具
print(datetime.now())            # 现在的时间

# 方式3:进货并起个小名(AI 库里常见,如 import pandas as pd)
import random as rd
print(rd.choice(["A", "B", "C"]))  # 随机选一个
👶 自带 vs 要装random / math / datetime / json 这些是 Python 自带零件,直接 import 就行;而 requests / openai / pandas 这些是第三方零件,得先 pip install 才能 import(回忆 Day02 的调料超市)。报错 ModuleNotFoundError,十有八九就是忘了先装。
L04

try / except:给程序装安全网

🤔 痛点程序难免遇到意外:网络断了、文件不存在、用户输入乱七八糟。一出意外整个程序"啪"地崩掉,后面的活全废了。
💡 本质try = "试着做这件可能出错的事";except = "万一摔了,安全网接住,做点补救而不是让全线停摆"。像产线装安全网:一个零件坏了,报警换掉,产线继续跑。
try:
    age = int(input("请输入年龄:"))   # 用户可能乱输,int() 转换会失败
    print(f"明年你 {age + 1} 岁")
except ValueError:                     # 专门接"值转换错误"这种意外
    print("输入的不是数字,请重新来 🙅")
print("程序继续往下跑,没有崩")        # 无论上面成败,这行都会执行

# 调 API / 读文件 最常这么写:出错了给个兜底,不让程序死
try:
    with open("config.txt") as f:
        data = f.read()
except FileNotFoundError:              # 文件不存在
    data = "默认配置"                  # 兜底方案
    print("没找到配置文件,用默认值")

👶 小白:那我是不是该给每行代码都套上 try/except,图个安心?

👨‍🏫 老师:别!套太多反而把真正的 bug 藏起来,出了错你还不知道。只在"预料到可能出意外、且你有补救办法"的地方用——典型三处:调外部 API(网络会抖)、读写文件(文件可能不在)、处理用户输入(什么都可能输)。这三处是重灾区,后面写 Agent 调工具时,try/except 让"一个工具挂了不拖垮整个 Agent",是可靠性的基本功(Day 32、Day 54 会深讲)。

L05

虚拟环境 venv:每个项目一间独立车间

🤔 痛点项目 A 要 requests 老版本,项目 B 要新版本;全装在一起会打架。而且所有包堆在系统里,迟早乱成一锅粥。
💡 本质虚拟环境=给每个项目开一间"独立车间",这个项目要装的包只待在自己车间里,不污染系统、不和别的项目串味。这是专业开发的标配习惯,从今天起养成。
# 进入你的项目文件夹后,创建一间叫 .venv 的独立车间
python -m venv .venv

# 进入(激活)这间车间 —— 命令分系统:
# macOS / Linux:
source .venv/bin/activate
# Windows(PowerShell):
.venv\Scripts\Activate.ps1

# 激活成功后,命令行前面会出现 (.venv) 字样
# 此后 pip install 装的包,只进这间车间,干净隔离

# 干完活想出车间:
deactivate
没有虚拟环境 vs 有虚拟环境 ❌ 全堆在系统里 项目A的包 + 项目B的包 版本互相打架、越来越乱 改一个项目,别的可能坏 ✅ 各有独立车间 A 的 .venv | B 的 .venv 互不干扰、想删整间删掉 干净、可复现、专业标配
图注:养成"新项目先建 venv"的肌肉记忆。这也是你以后跑任何 AI 项目 README 里的第一步。
L06

pip 依赖管理:记下车间的"进货清单"

🤔 痛点项目装了七八个包,换台电脑、或同事要跑,难道一个个回忆"我都装了啥"?
💡 本质用一个 requirements.txt 文件记下"进货清单"(装了哪些包、什么版本)。别人拿到清单,一句命令就能把车间原样复制出来。这就是项目"可复现"的关键。
# 在激活的虚拟环境里,装几个包
pip install requests openai

# 把当前车间的所有包 + 版本,导出成清单文件
pip freeze > requirements.txt
# 生成的文件里长这样:requests==2.31.0 / openai==1.30.0 ...

# 换台电脑 / 同事拿到项目:建好 venv 激活后,一键照单进货
pip install -r requirements.txt      # -r 表示"按这个清单文件装"
📝 举个例子:这就是你以后跑开源 AI 项目的标准三步 以后从 GitHub 下载任何 AI 项目,README 几乎都是这套:
python -m venv .venv 建车间 → ② source .venv/bin/activate 进车间 → ③ pip install -r requirements.txt 照单进货。
今天这两讲(venv + requirements),直接决定你后面能不能顺利跑通别人的代码——含金量极高,务必动手一遍。
L07

今日小结 + 动手 10 分钟

🧠 今天你应该能回答

  • 类和对象什么关系?属性和方法分别是啥?对象.方法() 怎么读?
  • self 大概指什么?(这一台对象自己)
  • import 干嘛?"自带模块"和"要 pip 装的"怎么区分?
  • try/except 解决什么问题?该在哪三类地方用?
  • 为什么每个项目都要建虚拟环境?requirements.txt 有什么用?

✋ 动手 10 分钟:建车间 + 写个小类

先在终端把"建车间"流程走一遍(这是最该练熟的):

mkdir day05_demo && cd day05_demo   # 建文件夹并进入
python -m venv .venv                 # 建车间
source .venv/bin/activate            # 进车间(Windows 用 .venv\Scripts\Activate.ps1)
pip install requests                 # 进点货
pip freeze > requirements.txt        # 导出清单
cat requirements.txt                 # 看看清单长啥样

再新建 day05.py,把类 + 方法 + try/except 串起来:

class Account:                       # 一张"账户"图纸
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    def withdraw(self, amount):      # 取款方法
        try:
            amount = int(amount)     # 可能传进来不是数字
            if amount > self.balance:
                print("余额不足 🙅")
            else:
                self.balance -= amount
                print(f"{self.owner} 取 {amount},剩余 {self.balance}")
        except ValueError:
            print("金额必须是数字")

a = Account("小明", 100)
a.withdraw(30)       # 小明 取 30,剩余 70
a.withdraw(200)      # 余额不足 🙅
a.withdraw("abc")    # 金额必须是数字(被 try/except 接住,程序不崩)
明日预告 · Day 06:Python 语法就此打住,明天换个战场——命令行 & Git。学会在黑框框里 cd/ls/mkdir 自如穿梭,更重要的是用 Git 给代码"存档 + 记录每次修改"(git init/add/commit/push),并把项目推上 GitHub。GitHub 是你转行路上的"作品陈列柜",面试官会看——越早开始攒越好。
← Day 04 · Python 极速入门② Day 06 · 命令行 & Git 基础 →