查看全课大纲(第 35 / 51 节)
- 1.为什么人人都该学点编程?
- 2.计算机与程序设计:你的电脑到底在“想”什么?
- 3.Python 这门语言,到底有什么魔力?
- 4.Python 开发环境配置:如何拥有你的第一个“编程工具箱”?
- 5.如何安装一个更强大的代码编辑器?
- 6.汇率兑换1.0:你的第一个“钱生钱”小程序
- 7.你的第一行代码,藏着哪些秘密?
- 8.汇率兑换2.0(上):让程序看懂“CNY”和“USD”
- 9.汇率兑换程序,如何让它“聪明”地判断币种?
- 10.汇率兑换程序能一直运行,直到我喊停吗?
- 11.汇率兑换4.0:如何把“算钱”功能打包成积木?
- 12.汇率兑换5.0:给你的程序穿上“结构化”的西装
- 13.怎么用 Python 画一个会动的五角星?
- 14.如何让程序自动画出不同大小的五角星?
- 15.函数自己调用自己,会发生什么?
- 16.用递归画出神奇的分形树
- 17.Python 怎么计算你一天躺着不动能消耗多少热量?
- 18.如何让程序“活”起来,持续为你服务?
- 19.如何让 BMR 计算器更“聪明”?
- 20.当程序遇到“不按套路出牌”的用户怎么办?
- 21.怎么用 Python 模拟一个“滚雪球”式的存钱计划?
- 22.如何用列表记录每一周的存款?
- 23.如何让程序自己数数?—— 用 for 循环解放你的双手
- 24.52周存钱挑战4.0:你的存款计算器能有多灵活?
- 25.52周存钱挑战:怎么根据日期自动查存款?
- 26.Python 怎么判断一年中的第几天?
- 27.列表 vs 元组:哪个更适合存储月份天数?
- 28.用集合给月份分个队,换个思路算天数
- 29.把月份和天数“锁”在一起:用字典给数据配个对
- 30.Python 怎么判断密码强弱?
- 31.Python 怎么给密码设置“防沉迷”系统?
- 32.Python 怎么把密码保存到文件里?
- 33.Python 怎么读取文件里的密码?
- 34.Python 怎么把密码检查工具“打包”起来?
- 35.Python 怎么把文件操作也“打包”起来?
- 36.计算机怎么“扔骰子”?——用Python模拟随机事件
- 37.如何用 Python 模拟掷两个骰子?
- 38.怎么用 Python 把骰子轨迹画出来?
- 39.骰子点数分布长啥样?用直方图一眼看穿!
- 40.用科学计算库让骰子程序“起飞”
- 41.空气质量指数怎么算?手把手教你写一个AQI计算器
- 42.空气质量指数计算:从零开始,让程序看懂空气
- 43.如何读取空气质量数据文件并找出空气质量最好的五个监测点?
- 44.JSON 数据怎么变成 Excel 表格?—— 让数据换个“马甲”
- 45.Python 怎么让程序自己判断文件类型?
- 46.如何让程序自己上网查空气质量?
- 47.用美味的汤来解析网页:Beautiful Soup 入门
- 48.如何让爬虫自动抓取全国所有城市的空气质量?
- 49.爬到的数据怎么存下来?—— 把全国空气质量数据保存为CSV文件
- 50.用 pandas 玩转空气质量数据:找出全国空气最好和最差的城市
- 51.空气质量数据怎么“洗”干净,还能画成图?
Python 怎么把文件操作也“打包”起来?
约 15 分钟
小象实战讲义 · Python 入门:8 个小项目边玩边学
欢迎来到密码强度判断项目的最终章!经过前面五节课的“修炼”,我们已经把密码相关的逻辑都封装成了一个帅气的 PasswordTool 类。这节课,我们要完成最后一块拼图:把文件读写操作也“打包”成一个工具类。这样,你的主程序就会变得超级清爽,一眼就能看懂它在干什么。准备好迎接“封装”思想的毕业典礼了吗?
💡 核心导读
- 本节新增:创建一个专门处理文件读写的
FileTool类。 - 温故知新:巩固上节课学的面向对象编程思想,特别是“封装”的好处。
- 项目收官:完成密码强度判断项目的最终形态,主程序逻辑清晰、易于维护。
- 知识扩展:了解面向对象的三大特点:封装、继承、多态(咱们先掌握封装就够啦)。
1. 回顾与目标:让程序更“干练”
还记得我们上节课的成果吗?我们把所有和密码判断相关的代码都塞进了一个叫 PasswordTool 的“工具箱”里。用的时候,只需要 password_tool = PasswordTool(你的密码),然后调用它的方法就行了,根本不用管里面是怎么实现的。
这感觉是不是很棒?代码一下子变整洁了。这节课,我们要对文件操作做同样的事情。现在,每次读写文件,我们都要写 open、write/readlines、close 这三步。能不能也把它们打包成一个“文件工具箱”呢?
当然可以!这就是我们 6.0 版本要做的唯一一件事:创建一个 FileTool 类。
2. 打造你的“文件工具箱”:FileTool 类
我们来一步步打造这个工具箱。它的核心功能就两个:写一行内容到文件,以及从文件读取所有行。
# 文件工具类 FileTool
class FileTool:
"""
文件工具箱
职责:专门负责文件的读写操作
"""
def __init__(self, filepath):
"""初始化工具箱,告诉它要操作哪个文件"""
self.filepath = filepath # 把文件路径保存起来,方便后续使用
def write_to_file(self, line):
"""写操作:把一行文本追加到文件末尾"""
f = open(self.filepath, 'a') # 以追加模式打开文件
f.write(line) # 写入传入的这一行内容
f.close() # 关闭文件,好习惯!
def read_from_file(self):
"""读操作:从文件中读取所有行,并返回一个列表"""
f = open(self.filepath, 'r') # 以只读模式打开文件
lines = f.readlines() # 读取所有行,得到一个字符串列表
f.close() # 关闭文件
return lines # 把读取到的内容列表返回给调用者看,这个类多清晰!__init__ 是它的“入职登记”,告诉它要操作哪个文件。write_to_file 和 read_from_file 是它的两个“技能”。以后任何想读写这个文件的地方,直接找这个工具箱就行了。
3. 使用工具箱:让主程序焕然一新
工具箱造好了,现在来看看怎么在咱们的主程序里用它,效果立竿见影!
def main():
"""
主函数
"""
try_times = 5
filepath = 'password_6.0.txt' # 定义要操作的文件名
# 🎯 关键一步:实例化文件工具对象
# 告诉文件工具箱:"你以后就专门操作 'password_6.0.txt' 这个文件"
file_tool = FileTool(filepath)
while try_times > 0:
password = 'Hello123' # 原程序用 input() 让用户输入,这里用固定值代替(对齐本节完整程序的示例),你可以改成自己的值试
# 实例化密码工具对象(上节课的内容)
password_tool = PasswordTool(password)
password_tool.process_password()
line = '密码:{}, 强度:{}\n'.format(password, password_tool.strength_level)
# ✨ 使用文件工具箱进行写操作
# 就这么简单一句话!背后的 open, write, close 工具箱都帮你搞定了
file_tool.write_to_file(line)
if password_tool.strength_level == 3:
print('恭喜!密码强度合格!')
break
else:
print('密码强度不合格!')
try_times -= 1
print()
if try_times <= 0:
print('尝试次数过多,密码设置失败!')
# ✨ 使用文件工具箱进行读操作
# 同样简单,调用方法,拿到结果
lines = file_tool.read_from_file()
print('文件中保存的所有记录:')
for line in lines:
print(line.strip()) # .strip() 去掉每行末尾的换行符为了让这段代码能直接运行,我们需要把之前定义的 PasswordTool 类和 FileTool 类都放在前面。同时,我们用固定值模拟 input() 输入。
# 完整的、可运行的 6.0 版本程序
class PasswordTool:
"""密码工具类"""
def __init__(self, password):
self.password = password
self.strength_level = 0
def process_password(self):
if len(self.password) >= 8:
self.strength_level += 1
else:
print('密码长度要求至少8位!')
if self.check_number_exist():
self.strength_level += 1
else:
print('密码要求包含数字!')
if self.check_letter_exist():
self.strength_level += 1
else:
print('密码要求包含字母!')
def check_number_exist(self):
has_number = False
for c in self.password:
if c.isnumeric():
has_number = True
break
return has_number
def check_letter_exist(self):
has_letter = False
for c in self.password:
if c.isalpha():
has_letter = True
break
return has_letter
class FileTool:
"""文件工具类"""
def __init__(self, filepath):
self.filepath = filepath
def write_to_file(self, line):
f = open(self.filepath, 'a')
f.write(line)
f.close()
def read_from_file(self):
f = open(self.filepath, 'r')
lines = f.readlines()
f.close()
return lines
# 主程序开始
try_times = 5
filepath = 'password_6.0.txt'
# 本节需要 password_6.0.txt(课程 resources 附件提供);为便于单独运行,
# 先用空文件重建一次,保证每次运行都从"空日志"开始(write_to_file 是追加模式,
# 若沿用上次的旧文件,读出来的记录会一次比一次多)
with open(filepath, 'w', encoding='utf-8') as f: # 示例数据:每次运行都重建,保证输出一致
f.write('')
file_tool = FileTool(filepath)
# 模拟用户输入,这里固定为'Hello123',你可以改成其他密码测试
password = 'Hello123' # 原程序这里是 input('请输入密码:')
password_tool = PasswordTool(password)
password_tool.process_password()
line = '密码:{}, 强度:{}\n'.format(password, password_tool.strength_level)
file_tool.write_to_file(line)
if password_tool.strength_level == 3:
print('恭喜!密码强度合格!')
else:
print('密码强度不合格!')
# 读操作演示
print('\n--- 读取文件内容 ---')
lines = file_tool.read_from_file()
for line in lines:
print(line.strip())运行上面的代码,你会看到类似下面的输出:
恭喜!密码强度合格!
--- 读取文件内容 ---
密码:Hello123, 强度:3是不是非常清晰?主程序里再也没有乱七八糟的 open 和 close 了,只有清晰的业务逻辑:“写日志”、“读日志”。这就是封装的魅力:隐藏复杂细节,提供简单接口。
4. 面向对象“三剑客”:封装、继承、多态
我们这两节课都在干一件事:封装。这是面向对象编程最核心、也是你现阶段最需要掌握的思想。简单说,封装就是“打包”,把相关的数据(属性)和操作(方法)塞进一个类里,用的时候整个拿来,不用关心内部细节。
面向对象还有两个著名的特点,我们简单了解一下,就像认识新朋友先知道名字:
- 继承:就像“子承父业”。可以创建一个新的类(子类),直接拥有另一个类(父类)的所有属性和方法,然后还可以添加自己特有的东西。
class Human: # 父类:人类
def speak(self):
print("人类会说话")
class Chinese(Human): # 子类:中国人,继承自Human
# Chinese 自动拥有了 speak 方法
def speak_chinese(self): # 自己特有的方法
print("你好!")- 多态:字面意思是“多种形态”。指的是同一个方法名,在不同的类里可以有不同的实现。比如,
Human和Dog类都可以有speak()方法,但人说话和狗叫的实现完全不同。程序会根据对象的实际类型来调用正确的方法。
对于零基础入门的你,牢牢掌握“封装”就足够了。它能立刻让你的代码变得更有条理、更好维护。继承和多态是更高级的武器,等你在编程世界里继续探险时自然会用上。
5. 项目大总结:我们这六节课都学了啥?
恭喜你!完成了“判断密码强弱”这个完整的小项目。让我们回顾一下这趟旅程:
- 1.0:巩固基础。用字符串方法(
isnumeric(),isalpha())和分支结构实现核心判断逻辑。 - 2.0:流程控制。引入循环和
break,让用户可以多次尝试,并学会何时跳出循环。 - 3.0:数据持久化。学习文件写操作(
open,write,close),把密码和强度保存到硬盘,让程序有了“记忆”。 - 4.0:读取历史。学习文件读操作(
readlines),能把保存的记录再读出来看看。 - 5.0:第一次封装。创建
PasswordTool类,把散落的密码判断逻辑打包成一个整洁的工具箱。这是面向对象编程的初体验。 - 6.0:第二次封装。创建
FileTool类,把文件操作也打包。至此,主程序变得非常简洁优雅,真正体现了封装的价值。
从一行行散乱的代码,到组织成两个职责分明的类,你的编程思维完成了一次重要的升级!
📝 动手练一练
- 增强密码规则:我们目前的规则只检查是否有字母,不区分大小写。请修改
PasswordTool类,增加一条规则:密码必须同时包含大写字母和小写字母。(提示:使用字符串的.isupper()和.islower()方法遍历判断) - 增加特殊符号:让密码强度要求更高,增加一条规则:密码必须至少包含一个特殊符号(如
+,-,*,$,@等)。思考一下,如何判断一个字符是不是特殊符号呢?(提示:可以定义一个包含所有允许的特殊符号的字符串,然后检查密码中是否有字符在这个字符串里)。
👉 点击查看第1题参考答案
思路:
- 在
process_password方法中增加第四个判断规则。 - 需要两个布尔标记:
has_upper和has_lower,初始都为False。 - 遍历密码字符串,如果发现大写字母,
has_upper设为True;发现小写字母,has_lower设为True。 - 如果最后
has_upper和has_lower都为True,则强度加1,否则提示用户。
关键代码片段:
# 在 PasswordTool 类的 process_password 方法中增加:
has_upper = False
has_lower = False
for c in self.password:
if c.isupper():
has_upper = True
if c.islower():
has_lower = True
if has_upper and has_lower:
self.strength_level += 1
else:
print('密码要求同时包含大写和小写字母!')记得把合格的标准从3改为4哦(if password_tool.strength_level == 4:)。
👉 点击查看第2题参考答案
思路:
- 定义一个字符串,包含所有你认可的特殊符号,例如
special_chars = "+-*$@#!&"。 - 在
process_password方法中增加判断。 - 遍历密码字符串,检查每个字符是否在
special_chars字符串中(使用in关键字)。 - 如果找到任何一个,则强度加1,否则提示用户。
关键代码片段:
# 在 PasswordTool 类的 process_password 方法中增加:
special_chars = "+-*$@#!&" # 你可以自己增减特殊符号
has_special = False
for c in self.password:
if c in special_chars:
has_special = True
break # 找到一个就够了,可以提前结束循环
if has_special:
self.strength_level += 1
else:
print('密码要求包含特殊符号(如 +, -, *, $, @ 等)!')同样,合格的标准需要相应提高。
本章小结
了不起!你不仅完成了一个实用的密码强度判断工具,更重要的是,你亲身体验了如何将一个想法,从简单的脚本(1.0),一步步迭代、完善,最终构建成一个结构清晰、易于理解和扩展的“专业范儿”程序(6.0)。这个“螺旋式迭代”的过程,正是本课程希望你掌握的核心学习方式。
📋 行动清单
学完本章,你可以立刻:
- 运行最终的 6.0 版本程序,体验一下封装后主程序的简洁。
- 动手完成上面的练习,为你自己的密码判断工具增加更强大的规则。
- 思考:在你的生活或工作中,有没有什么重复性的、可以“打包”成工具的任务?(比如整理文件、计算开销等)用编程思维想一想。
面向对象编程的大门已经为你打开,封装的思想将伴随你整个编程生涯。接下来,我们将进入一个全新的、充满随机性的项目,一起用 Python 来“模拟掷骰子”,探索概率的奥秘!
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。
- 下载第7章代码包:判断密码强弱(含全部版本 6 个 .py)ZIP · 5KB