大一新生 × AI Coding:从游戏到记账本,我如何用DeepSeek写出第二个Python项目
前言
如果你是从上一篇《大一新生 × AI Coding:从概念到实践,我如何用DeepSeek做出第一个Python游戏》过来的,那么恭喜你,你已经拥有了和计算机“对话”的初级能力。
今天我们趁热打铁,来做一个更贴近生活的实用小工具——命令行记账本。
它能帮你记录每天的收支、自动计算余额,而且数据会保存在文件里,关机再开也不会丢。
全程依然是零基础友好,你只需要跟着我一步步操作,你的第二个 Python 项目就能跑起来。
一、项目功能说明
这个命令行记账本支持以下操作:
-
记录收入:输入金额和说明(比如“生活费 +2000”)
-
记录支出:输入金额和说明(比如“奶茶 -15”)
-
查看当前余额:自动计算总收入减去总支出
-
查看所有收支明细:按时间顺序列出每一笔账
-
数据自动保存到文件(
account_book.json) -
启动时自动加载历史数据,关掉程序再打开,账本还在
运行起来的主菜单长这样:
========== 简易记账本 ==========
-
记录收入
-
记录支出
-
查看余额
-
查看明细
-
退出
请选择操作(1-5):
是不是感觉像个真正的软件了?实际上它的核心代码只有不到 100 行。
二、实现思路
我们用一种“先想清楚再动手”的方式来拆解这个项目:
-
数据存储:用 Python 的列表(list)来装所有记录,每一条记录是一个字典(dict),包含:类型、金额、说明、时间。
-
文件保存:用 JSON 格式把列表存到文件里(
account_book.json),下次启动时读回来。JSON 的好处是人和机器都能看懂。 -
主程序结构:一个
while True无限循环,显示菜单,根据用户输入的数字调用不同的函数。 -
余额计算:遍历所有记录,收入就加,支出就减。
这种“数据 + 操作”的模式,其实就是最朴素的编程思维。
三、第一步:搭建 Python 环境(已有可跳过)
如果你已经跟着第一篇装好了 Python,打开命令提示符输入 python --version 能正常显示版本号,那就可以直接跳到下一步。
如果你还没装,或者不确定,请回到上一篇的 “三、第一步:搭建 Python 环境” 部分,跟着截图一步步安装,几分钟就能搞定。

四、第二步:创建项目文件
我们需要新建一个 .py 文件来装记账本的代码。
-
在桌面空白处右键 → 新建 → 文本文档
-
确保能看到文件扩展名(如果看不到
.txt,打开任意文件夹 → 顶部“查看” → 勾选“文件扩展名”) -
把
新建文本文档.txt重命名为account_book.py
⚠️ 注意:后缀一定要从.txt变成.py,系统会提示“改变扩展名可能导致文件不可用”,点“是”就行。

五、第三步:向 DeepSeek 提问,生成初版代码
打开 DeepSeek(网页版或 App 都可以),选择专家模式,然后把下面这段话复制进去:
用Python写一个命令行记账本程序,功能包括:
-
记录收入(输入金额和说明)
-
记录支出(输入金额和说明)
-
查看当前余额
-
查看所有收支明细
-
数据保存在JSON文件中,下次启动时自动加载
代码要附带详细注释,适合初学者阅读。

DeepSeek 会很快返回一段完整的代码。全选复制,然后我们把它粘贴到 account_book.py 里。
下面是它生成的核心代码(你可以直接对照检查):
text
"""
简单命令行记账本程序
功能:
- 记录收入(金额 + 说明)
- 记录支出(金额 + 说明)
- 查看当前余额
- 查看所有收支明细
- 数据自动保存到 JSON 文件,下次启动时自动加载
"""
import json
import os
from datetime import datetime
class Ledger:
"""记账本类,负责管理收支记录和文件读写"""
def __init__(self, filename="ledger_data.json"):
"""
初始化记账本
:param filename: 保存数据的 JSON 文件名
"""
self.filename = filename
self.transactions = [] # 存储所有收支记录的列表,每条记录是一个字典
self.load_data() # 启动时加载已有数据
def load_data(self):
"""从 JSON 文件加载历史数据,如果文件不存在则忽略"""
if os.path.exists(self.filename):
try:
with open(self.filename, "r", encoding="utf-8") as f:
self.transactions = json.load(f)
print(f"已加载历史数据,共 {len(self.transactions)} 条记录。")
except (json.JSONDecodeError, IOError):
print("数据文件损坏或无法读取,将使用空账本。")
self.transactions = []
else:
print("未找到历史数据文件,将创建新账本。")
def save_data(self):
"""将当前所有交易记录保存到 JSON 文件"""
try:
with open(self.filename, "w", encoding="utf-8") as f:
json.dump(self.transactions, f, ensure_ascii=False, indent=4)
print("数据已保存。")
except IOError as e:
print(f"保存数据时出错:{e}")
def add_income(self, amount, description):
"""
添加一笔收入记录
:param amount: 收入金额(正数)
:param description: 收入说明
"""
if amount <= 0:
print("错误:收入金额必须大于0。")
return
if not description.strip():
print("错误:说明不能为空。")
return
# 创建一条记录,包含类型、金额、说明和时间戳
transaction = {
"type": "income",
"amount": amount,
"description": description.strip(),
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
self.transactions.append(transaction)
self.save_data()
print(f"收入记录已添加:+{amount:.2f} 元,说明:{description}")
def add_expense(self, amount, description):
"""
添加一笔支出记录
:param amount: 支出金额(正数)
:param description: 支出说明
"""
if amount <= 0:
print("错误:支出金额必须大于0。")
return
if not description.strip():
print("错误:说明不能为空。")
return
transaction = {
"type": "expense",
"amount": amount,
"description": description.strip(),
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
self.transactions.append(transaction)
self.save_data()
print(f"支出记录已添加:-{amount:.2f} 元,说明:{description}")
def get_balance(self):
"""
计算当前余额:总收入 - 总支出
:return: 余额(浮点数)
"""
total_income = sum(t["amount"] for t in self.transactions if t["type"] == "income")
total_expense = sum(t["amount"] for t in self.transactions if t["type"] == "expense")
return total_income - total_expense
def show_balance(self):
"""在控制台打印当前余额"""
balance = self.get_balance()
print(f"\n当前余额:{balance:.2f} 元\n")
def show_transactions(self):
"""在控制台按时间顺序打印所有收支明细"""
if not self.transactions:
print("\n还没有任何收支记录。\n")
return
print("\n========== 所有收支明细 ==========")
# 按时间顺序显示(记录添加的顺序)
for idx, t in enumerate(self.transactions, start=1):
type_str = "收入" if t["type"] == "income" else "支出"
sign = "+" if t["type"] == "income" else "-"
print(f"{idx}. [{t['timestamp']}] {type_str}: {sign}{t['amount']:.2f} 元")
print(f" 说明:{t['description']}")
print("==================================\n")
def show_menu():
"""显示主菜单选项"""
print("========== 简单记账本 ==========")
print("1. 记录收入")
print("2. 记录支出")
print("3. 查看当前余额")
print("4. 查看所有收支明细")
print("5. 退出程序")
print("================================")
def get_positive_float(prompt):
"""
获取用户输入的正浮点数(金额)
如果输入无效或非正数,则提示重新输入
"""
while True:
try:
value = float(input(prompt))
if value <= 0:
print("金额必须大于0,请重新输入。")
continue
return value
except ValueError:
print("输入无效,请输入一个数字。")
def main():
"""主程序入口,处理用户交互"""
ledger = Ledger() # 创建账本实例,自动加载历史数据
while True:
show_menu()
choice = input("请输入选项(1-5):").strip()
if choice == "1":
# 记录收入
amount = get_positive_float("请输入收入金额:")
description = input("请输入收入说明:").strip()
ledger.add_income(amount, description)
elif choice == "2":
# 记录支出
amount = get_positive_float("请输入支出金额:")
description = input("请输入支出说明:").strip()
ledger.add_expense(amount, description)
elif choice == "3":
# 查看余额
ledger.show_balance()
elif choice == "4":
# 查看明细
ledger.show_transactions()
elif choice == "5":
# 退出程序
print("感谢使用,再见!")
break
else:
print("无效选项,请输入 1-5 之间的数字。")
if __name__ == "__main__":
main()
如何把代码放进文件?
-
右键点击桌面上的
account_book.py→ 打开方式 → 记事本 -
把上面复制下来的代码粘贴进去
-
按
Ctrl+S保存,然后关闭记事本
搞定!现在你的第一个记账本程序就已经“写”好了。

六、第四步:运行程序
和上次运行猜数字游戏一样,我们在命令行里启动它。
-
确保
account_book.py文件在桌面上。 -
在桌面空白处,按住键盘上的 Shift 键不放,同时点击鼠标右键。
-
在弹出的菜单里选择 “在此处打开 PowerShell 窗口”(Win10/11)或 “在此处打开命令窗口”。
-
在打开的蓝色或黑色窗口中输入以下命令,然后按回车:
text
python account_book.py
如果一切顺利,你会立刻看到主菜单:
========== 简易记账本 ==========
-
记录收入
-
记录支出
-
查看余额
-
查看明细
-
退出
请选择操作(1-5):

七、第五步:实际使用演示 + 数据持久化验证
现在我们来真实地记两笔账,看看效果。
操作过程
-
输入
1,记录收入:-
金额:
2000 -
说明:
生活费
-
-
输入
2,记录支出:-
金额:
35.5 -
说明:
买奶茶
-
-
输入
3,查看余额,显示:当前余额:1964.50 元 -
输入
4,查看明细,显示:
========== 收支明细 ==========
[2026-04-10 14:20:15] 收入 2000.00 元 说明:生活费
[2026-04-10 14:21:03] 支出 35.50 元 说明:买奶茶
==============================
-
输入
5,退出程序。


关键验证:数据真的保存了吗?
关掉命令行窗口,然后再次运行 python account_book.py。进入程序后直接按 4 查看明细——你会发现刚才的记录完完整整还在那里!
这是因为程序在同目录下生成了一个 account_book.json 文件,你可以用记事本打开它看看:
text
[
{
"type": "收入",
"amount": 2000.0,
"desc": "生活费",
"time": "2026-04-10 14:20:15"
},
{
"type": "支出",
"amount": 35.5,
"desc": "买奶茶",
"time": "2026-04-10 14:21:03"
}
]
这种关了再开数据还在的能力,在编程里叫数据持久化。这也是我们这个记账本区别于上一篇猜数字游戏的最大进步。

八、第六步:迭代改进——增加删除记录功能(可选)
用了一天后,我发现一个问题:万一我不小心输错了金额,想删掉某条记录怎么办?现在还没有删除功能。
于是我又打开 DeepSeek,输入了新的需求:
请在上面的记账本代码中增加一个功能:删除记录。
用户选择删除后,先展示所有记录并编号,然后让用户输入要删除的编号,确认后删除对应记录并保存。
DeepSeek 很快给出了修改方案。主要改动是:
-
在主菜单增加选项
6. 删除记录 -
新增一个
delete_record()函数,用来展示带编号的记录并处理删除逻辑
核心代码片段大概是这样(你可以让 AI 生成完整版):
text
def delete_record():
if not records:
print("暂无记录可删除。")
return
print("\n========== 当前记录 ==========")
for i, r in enumerate(records, start=1):
print(f"{i}. [{r['time']}] {r['type']} {r['amount']} 元 {r['desc']}")
print("================================")
try:
num = int(input("请输入要删除的记录编号(输入0取消):"))
if num == 0:
return
if 1 <= num <= len(records):
deleted = records.pop(num - 1)
save_data()
print(f"已删除记录:{deleted['desc']} {deleted['amount']} 元")
else:
print("编号超出范围!")
except ValueError:
print("输入无效,请输入数字编号。")
你可以自己尝试把这个功能加到完整代码里。如果遇到报错,直接把错误信息复制给 DeepSeek,它会帮你改好。这也是 AI Coding 最好用的地方——它不仅是代码生成器,还是你的专属 debug 助手。

九、我学到了什么
从猜数字游戏到命令行记账本,我感觉自己好像升级了。这次我新掌握的东西包括:
-
文件操作:
open()、json.load()、json.dump(),知道怎么让数据“永久保存”。 -
结构化数据:列表里套字典,用起来非常灵活。
-
异常处理:
try...except防止用户乱输入导致程序崩溃。 -
模块化编程:一个功能一个函数,主函数只负责调度,代码清晰多了。
-
真实的开发流程:想功能 → 问 AI → 跑起来 → 发现问题 → 再问 AI 改进。
更重要的是,我开始理解编程不是背语法,而是用工具解决实际问题。AI 帮我跳过了那些让人头疼的语法细节,让我能直接看到成果,保持学习的动力。
十、下一步计划
目前我们已经有了两个命令行小工具:猜数字 + 记账本。接下来我想挑战一个带图形界面的程序。
Python 自带一个叫 tkinter 的库,可以轻松做出窗口、按钮、输入框。我打算用它做一个简单的计算器,或者一个备忘录。
等做出来了,我会继续写成第三篇博客。如果你跟着做到了这里,不妨在评论区告诉我,你的第二个 Python 项目跑起来了吗?遇到什么坑没有?
我们一起进步!
附录:完整代码(记账本基础版)
text
import json
import os
from datetime import datetime
DATA_FILE = "account_book.json"
records = []
def load_data():
global records
if os.path.exists(DATA_FILE):
with open(DATA_FILE, 'r', encoding='utf-8') as f:
records = json.load(f)
else:
records = []
def save_data():
with open(DATA_FILE, 'w', encoding='utf-8') as f:
json.dump(records, f, ensure_ascii=False, indent=2)
def add_income():
try:
amount = float(input("请输入收入金额:"))
if amount <= 0:
print("金额必须大于0!")
return
desc = input("请输入收入说明:")
record = {
"type": "收入",
"amount": amount,
"desc": desc,
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
records.append(record)
save_data()
print("收入记录已保存!")
except ValueError:
print("输入错误,请输入有效的数字!")
def add_expense():
try:
amount = float(input("请输入支出金额:"))
if amount <= 0:
print("金额必须大于0!")
return
desc = input("请输入支出说明:")
record = {
"type": "支出",
"amount": amount,
"desc": desc,
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
records.append(record)
save_data()
print("支出记录已保存!")
except ValueError:
print("输入错误,请输入有效的数字!")
def show_balance():
total = 0
for r in records:
if r["type"] == "收入":
total += r["amount"]
else:
total -= r["amount"]
print(f"当前余额:{total:.2f} 元")
def show_details():
if not records:
print("暂无任何记录。")
return
print("\n========== 收支明细 ==========")
for r in records:
print(f"[{r['time']}] {r['type']} {r['amount']:.2f} 元 说明:{r['desc']}")
print("==============================\n")
def main():
load_data()
while True:
print("\n========== 简易记账本 ==========")
print("1. 记录收入")
print("2. 记录支出")
print("3. 查看余额")
print("4. 查看明细")
print("5. 退出")
choice = input("请选择操作(1-5):")
if choice == '1':
add_income()
elif choice == '2':
add_expense()
elif choice == '3':
show_balance()
elif choice == '4':
show_details()
elif choice == '5':
print("再见!")
break
else:
print("输入无效,请重新选择。")
if __name__ == "__main__":
main()
本文代码由 DeepSeek 生成,作者已实际运行验证。
AI 声明:
本文由 DeepSeek 辅助生成代码和部分文案,所有步骤均经过本人实际操作验证。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)