阶段 1 python基础2
阶段 1:编程与服务基础
类与对象 / 异常处理 / 文件与 JSON / 模块化与 typing 核心笔记
2. 类与对象
2.1 基本概念
类(class)
类是对一类事物的抽象模板。
对象(object)
对象是类的具体实例。
例如:
- 类:学生
- 对象:张三、李四
class Student:
pass
s1 = Student()
s2 = Student()
2.2 为什么需要类
函数适合封装逻辑;类适合把:
- 数据
- 行为
组织到一起。
例如“用户”不仅有:
- name
- age
还会有行为:
- 登录
- 更新信息
这时用类更自然。
2.3 __init__ 构造方法
对象创建时,通常会执行 __init__ 初始化属性。
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
创建对象:
s = Student("Tom", 20)
print(s.name)
print(s.age)
核心理解
self代表当前对象本身self.name = name表示把传入参数保存到对象属性上
2.4 实例属性与实例方法
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
return f"我叫{self.name},今年{self.age}岁"
调用:
s = Student("Tom", 20)
print(s.introduce())
核心理解
- 属性:对象的数据
- 方法:对象的行为
2.5 self 是什么
self 表示“当前对象”。
class User:
def __init__(self, name):
self.name = name
这里:
- 左边
self.name是对象属性 - 右边
name是传进来的参数
self 不是关键字,但约定俗成必须这么写。
2.6 类属性与实例属性
实例属性
每个对象自己拥有。
class User:
def __init__(self, name):
self.name = name
类属性
所有对象共享。
class User:
species = "human"
def __init__(self, name):
self.name = name
u1 = User("Tom")
u2 = User("Alice")
print(u1.species)
print(u2.species)
区别
- 实例属性:每个对象不同
- 类属性:多个对象共享
2.7 面向对象三大基础认知
封装
把数据和操作数据的方法放在一起。
继承
子类复用父类能力。
多态
同样的方法名,在不同对象上有不同实现。
现阶段重点掌握:
- 类
- 对象
self- 属性与方法
2.8 简单继承
class Animal:
def speak(self):
return "..."
class Dog(Animal):
def speak(self):
return "wang"
子类可以:
- 继承父类方法
- 重写父类方法
2.9 难点与易错点
self 不能忘
class Student:
def introduce():
pass
实例方法里如果少了 self,调用会报错。
self.name 和 name 不要混
class Student:
def __init__(self, name):
self.name = name
name:参数self.name:对象属性
类更适合“有状态”的对象
例如:
- 聊天会话管理器
- 向量检索器
- 数据库客户端
- Agent 状态对象
2.10 工程场景
工具类
class PDFLoader:
def load(self, path):
...
服务类
class ChatService:
def generate(self, messages):
...
状态类
class AgentState:
def __init__(self):
self.messages = []
self.tools_used = set()
2.11 必须记住
- 类是模板,对象是实例
__init__用于初始化对象self表示当前对象- 属性表示数据,方法表示行为
- 类适合组织“数据 + 行为 + 状态”
3. 异常处理
3.1 什么是异常
异常是程序运行时出现的错误。
常见异常:
ValueErrorTypeErrorKeyErrorIndexErrorZeroDivisionErrorFileNotFoundError
例如:
int("abc") # ValueError
1 / 0 # ZeroDivisionError
3.2 为什么要处理异常
如果不处理,程序可能直接中断。
异常处理的目的:
- 防止程序崩溃
- 给出更清晰的错误信息
- 做兜底逻辑
- 提高系统稳定性
后续做 API、RAG、Agent 时都非常关键。
3.3 基本语法
try:
可能出错的代码
except 某种异常:
出错后的处理
示例:
try:
num = int("abc")
except ValueError:
print("输入不是合法整数")
3.4 捕获多个异常
try:
...
except ValueError:
...
except TypeError:
...
也可以写成:
try:
...
except (ValueError, TypeError):
...
3.5 except Exception as e
try:
...
except Exception as e:
print(e)
用途:
- 兜底捕获未知异常
注意:
- 不要一上来所有地方都只写
except Exception - 优先捕获明确异常,最后再做总兜底
3.6 else 和 finally
try:
x = int("123")
except ValueError:
print("转换失败")
else:
print("转换成功")
finally:
print("一定会执行")
含义
else:没有异常时执行finally:无论是否异常都会执行
典型用途:
- 关闭文件
- 释放资源
- 清理连接
3.7 主动抛出异常
def divide(a, b):
if b == 0:
raise ValueError("除数不能为 0")
return a / b
作用:
- 提前阻止非法输入
- 明确告诉调用方错误原因
3.8 难点与易错点
不要裸 except
错误写法:
try:
...
except:
...
问题:
- 把所有异常都吞掉
- 不利于定位问题
不要把异常处理当“隐藏错误”
应该:
- 记录异常原因
- 返回清晰错误信息
- 适当兜底
区分“能恢复”和“不能恢复”的错误
- 可恢复:输入格式错、文件不存在、网络超时
- 不可恢复:核心逻辑严重错误
3.9 工程场景
接口参数解析
try:
age = int(user_input)
except ValueError:
return {"error": "年龄必须是整数"}
文件读取
try:
with open("a.txt", "r", encoding="utf-8") as f:
content = f.read()
except FileNotFoundError:
print("文件不存在")
调用外部服务
- 网络请求失败
- 模型调用超时
- 数据库连接异常
这些都要有异常兜底。
3.10 必须记住
- 异常是运行时错误
try-except用于捕获异常finally常用于资源释放raise用于主动抛出异常- 异常处理的目标是:稳定 + 清晰 + 可排查
4. 文件与 JSON
4.1 文件操作基础
打开文件
f = open("a.txt", "r", encoding="utf-8")
常见模式
r:读w:写,覆盖原内容a:追加b:二进制
4.2 推荐写法:with
with open("a.txt", "r", encoding="utf-8") as f:
content = f.read()
好处:
- 自动关闭文件
- 更安全
- 更符合工程习惯
4.3 读取文件
一次性读全部内容
with open("a.txt", "r", encoding="utf-8") as f:
content = f.read()
按行读取
with open("a.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
或:
with open("a.txt", "r", encoding="utf-8") as f:
for line in f:
print(line)
4.4 写入文件
with open("a.txt", "w", encoding="utf-8") as f:
f.write("hello")
追加:
with open("a.txt", "a", encoding="utf-8") as f:
f.write("\nworld")
4.5 JSON 是什么
JSON 是后端和 AI 应用中最常见的数据交换格式。
典型特征:
- 对象:键值对
- 数组:列表
- 文本格式
- 跨语言通用
例如:
{
"name": "Tom",
"age": 20,
"skills": ["Python", "FastAPI"]
}
Python 中通常对应:
data = {
"name": "Tom",
"age": 20,
"skills": ["Python", "FastAPI"]
}
4.6 Python 读写 JSON
需要 json 模块。
JSON 字符串 -> Python 对象
import json
text = '{"name": "Tom", "age": 20}'
data = json.loads(text)
Python 对象 -> JSON 字符串
import json
data = {"name": "Tom", "age": 20}
text = json.dumps(data, ensure_ascii=False)
4.7 JSON 文件读写
读取 JSON 文件
import json
with open("data.json", "r", encoding="utf-8") as f:
data = json.load(f)
写入 JSON 文件
import json
data = {"name": "Tom", "age": 20}
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
4.8 load/loads 与 dump/dumps 区别
读取
json.load(f):从文件对象读取 JSONjson.loads(text):从字符串读取 JSON
写入
json.dump(data, f):写入文件json.dumps(data):转成 JSON 字符串
这是高频易混点。
4.9 难点与易错点
JSON 的 key 必须是字符串
虽然 Python dict 更灵活,但 JSON 对象的 key 通常是字符串。
Python 的单引号不是标准 JSON
Python dict:
{'name': 'Tom'}
标准 JSON:
{"name": "Tom"}
注意编码
读写中文文件或 JSON 时,常用:
encoding="utf-8"
文件模式要选对
w会覆盖原内容a才是追加
4.10 工程场景
配置文件
config = json.load(f)
保存模型返回结果
json.dump(result, f, ensure_ascii=False, indent=2)
接口请求 / 响应
FastAPI、前后端交互、模型调用都大量使用 JSON。
RAG 中的元数据缓存
文档块、索引信息、评测结果都可能落成 JSON。
4.11 必须记住
- 文件操作优先用
with open(...) r / w / a要分清- JSON 是最常用的数据交换格式
load/loads是读取dump/dumps是写出- JSON 和 Python 的
dict + list高度对应
5. 模块化与 typing
5.1 什么是模块化
模块化就是把代码拆分成多个文件、多个模块,让结构更清晰。
例如:
main.pyutils.pydb.pyservice.pyconfig.py
好处:
- 降低复杂度
- 方便维护
- 方便复用
- 方便多人协作
5.2 模块与导入
导入整个模块
import math
print(math.sqrt(16))
导入模块中的某个对象
from math import sqrt
print(sqrt(16))
起别名
import numpy as np
from math import sqrt as s
5.3 为什么要模块化
如果所有代码都写在一个文件里:
- 很难找
- 很难维护
- 很难测试
- 很难扩展
工程里常见拆法:
- 路由层
- 服务层
- 数据访问层
- 工具层
- 配置层
5.4 基本拆分思路
工具函数放到 utils.py
# utils.py
def clean_text(text):
return text.strip()
主程序中导入使用
from utils import clean_text
5.5 if __name__ == "__main__"
def main():
print("run")
if __name__ == "__main__":
main()
作用:
- 当前文件直接运行时执行
- 被别的文件 import 时不执行
这是 Python 模块化的重要基础。
5.6 什么是 typing
typing 是类型标注,用来提高代码可读性和可维护性。
它的目标不是改变 Python 的动态类型本质,而是:
- 让代码更清晰
- 让 IDE 更好提示
- 让类型检查工具更好发现问题
5.7 基本类型标注
def add(a: int, b: int) -> int:
return a + b
含义:
a是intb是int- 返回值是
int
5.8 常见类型标注
def greet(name: str) -> str:
return f"hello {name}"
def is_ok(flag: bool) -> bool:
return not flag
5.9 容器类型标注
现代 Python 常用:
def process(nums: list[int]) -> list[int]:
return nums
def build_user() -> dict[str, str]:
return {"name": "Tom"}
visited: set[str] = set()
如果环境较老,也可能见到:
from typing import List, Dict, Set
5.10 Optional
表示“这个值可能是某种类型,也可能是 None”。
from typing import Optional
def find_user(user_id: int) -> Optional[dict]:
...
含义:
- 返回值可能是
dict - 也可能是
None
5.11 Union / |
表示多种可能类型。
def parse_value(x: int | str) -> str:
return str(x)
老写法:
from typing import Union
def parse_value(x: Union[int, str]) -> str:
return str(x)
5.12 类型标注的意义
可读性更强
函数输入输出更清晰。
IDE 提示更准确
自动补全、跳转、报错更友好。
更适合工程开发
尤其在:
- FastAPI
- 数据处理
- 多模块项目
- 团队协作
场景里很有价值。
5.13 难点与易错点
类型标注不是强制运行时检查
def add(a: int, b: int) -> int:
return a + b
Python 运行时不会自动严格检查类型,类型标注主要服务于:
- 阅读
- IDE
- 静态检查工具
不要为了标注而过度复杂
现阶段重点是:
- 函数参数
- 返回值
- 常见容器
先把这些写清楚就够了。
模块划分不要过细也不要过乱
拆模块的目标是清晰,不是为了拆而拆。
5.14 工程场景
FastAPI
def chat(query: str, top_k: int = 3) -> dict:
...
RAG
def retrieve(query: str) -> list[dict]:
...
Agent
class AgentState:
messages: list[dict]
tools_used: set[str]
这些场景中,模块化和 typing 都会让代码结构更稳。
5.15 必须记住
- 模块化是为了让代码可维护
import/from ... import ...要会看懂if __name__ == "__main__"是模块运行入口控制- 类型标注提升可读性和工程性
- 现阶段优先掌握:参数类型、返回值类型、常见容器类型
总结:这 5 块的主线
1. 数据结构
解决:数据如何组织
2. 类与对象
解决:数据和行为如何一起组织
3. 异常处理
解决:出错时如何兜底与保持稳定
4. 文件与 JSON
解决:数据如何落盘、读取、交换
5. 模块化与 typing
解决:代码如何变得更清晰、更适合工程开发
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)