查看全课大纲(第 34 / 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 怎么把密码检查工具“打包”起来?
约 22 分钟
小象实战讲义 · Python 入门:8 个小项目边玩边学
欢迎回来!经过前面几个版本的迭代,我们的密码强度检查程序已经相当能干了:能检查、能循环、能存文件、能读文件。但你不觉得主程序越来越像一个“大杂烩”吗?各种功能混在一起,想改个规则都得在代码里翻半天。
这一节,我们要做一件很酷的事:把跟密码相关的所有“零件”(检查数字、检查字母、计算强度)都装进一个“工具箱”里。以后你想检查密码,直接打开这个工具箱用就行,不用再关心里面螺丝刀是怎么转的。这个“打包”的过程,在编程世界里有一个响亮的名字——面向对象编程。
学完这一节,你的程序会变得结构清晰、主次分明,主程序可能只剩下短短几行,但功能一点没少!这就像从“手工组装电脑”升级到了“买品牌整机”,省心又专业。
💡 核心导读
- 认识编程的“两大门派”:面向过程 vs. 面向对象,它们看待问题的角度有何不同?
- 什么是“对象”和“类”:用生活中的猫和车来理解这两个核心概念。
- 打造专属“密码工具箱”:我们将创建一个
PasswordTool类,把所有密码检查逻辑都封装进去。 - 体验“封装”的魔力:主程序变得异常简洁,你只需要知道“怎么用”,不用管“怎么实现”。
编程的“两大门派”:过程派 vs. 对象派
在编程江湖里,主要有两大思想流派,它们看待和解决问题的方式很不一样。
第一派:面向过程 (Procedure-Oriented Programming, POP)
- 核心思想:以程序的执行过程为中心。就像我们之前写的代码,先输入密码,然后检查长度,再检查数字,最后检查字母,一步接一步,画出流程图就能直接转换成代码。
- 优点:思路直接,符合我们一步一步解决问题的习惯。
- 我们之前写的所有版本,都属于面向过程。
第二派:面向对象 (Object-Oriented Programming, OOP)
- 核心思想:以事物为中心。我们把要处理的东西(比如“密码”)看作一个独立的“对象”,然后思考这个对象有什么特征(属性),能做什么动作(方法)。
- 优点:更贴近现实世界的思维方式,代码结构清晰,易于维护和复用。
- 本节,我们就要迈入面向对象的大门!
从现实世界理解“对象”和“类”
什么是对象 (Object)? 对象就是现实世界中的任何具体事物。每个对象通常包含两样东西:
- 属性 (Attribute):描述对象静态特征的。比如一只波斯猫,它的品种、颜色、大小就是属性。
- 行为 (Behavior):描述对象动态动作的。比如这只猫会叫、会跑、会捉老鼠,这些就是它的行为。
再比如一辆吉普车,它的类型、用途、马力是属性;发动、停车、拐弯是行为。
什么是类 (Class)? 类是对象的抽象和模板,是“一类”事物的总称。对象是类的具体实例。
它们的关系就像“汽车设计图”和“真正的汽车”:
- 类 (Car):是设计图,定义了汽车应该有轮子、发动机、能跑等共性。
- 对象 (你的 Polo 车,朋友的 Mini Cooper):是根据设计图制造出来的、实实在在的、各不相同的汽车。
从对象归纳出类的过程叫抽象;用类创造出具体对象的过程叫实例化。
打造我们的“密码工具箱”:PasswordTool 类
理解了概念,我们动手把之前散落的密码检查功能,封装成一个 PasswordTool(密码工具)类。
class PasswordTool:
"""
密码工具类
负责封装所有与密码强度检查相关的逻辑
"""
def __init__(self, password):
# 类的属性(静态特征)
self.password = password # 要检查的密码字符串
self.strength_level = 0 # 密码强度等级,初始为0
def process_password(self):
"""
处理密码,应用所有规则并计算最终强度等级
"""
# 规则1:密码长度大于8
if len(self.password) >= 8:
self.strength_level += 1
else:
print('密码长度要求至少8位!')
# 规则2:包含数字
if self.check_number_exist():
self.strength_level += 1
else:
print('密码要求包含数字!')
# 规则3:包含字母
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(): # isnumeric() 判断字符是否为数字
has_number = True
break
return has_number
def check_letter_exist(self):
"""
判断字符串中是否含有字母
"""
has_letter = False
for c in self.password:
if c.isalpha(): # isalpha() 判断字符是否为字母
has_letter = True
break
return has_letter代码解读:
class PasswordTool::用class关键字定义一个类,类名通常首字母大写。__init__(self, password)::这是一个特殊的初始化方法(构造函数)。当你创建一个PasswordTool对象时,它会自动被调用。self:代表类实例自身,通过self.属性名来定义或访问属于这个对象的属性。- 我们在这里初始化了两个属性:
self.password(传入的密码)和self.strength_level(强度等级,初始为0)。
process_password(self)::这是我们新增的核心方法。它把三条检查规则的组织逻辑放在了一起,并更新strength_level。check_number_exist(self)和check_letter_exist(self):这两个是具体的检查方法。注意,因为它们也是类的方法,所以第一个参数也是self。在方法内部,我们通过self.password来访问当前对象要检查的密码。- 关键变化:所有方法内部需要用到密码时,不再从参数传入,而是直接使用
self.password。需要修改强度等级时,就操作self.strength_level。
如何使用“工具箱”?主程序大变身!
定义了强大的工具箱后,我们的主程序就变得超级简洁和清晰。下面是包含 PasswordTool 类与主程序的完整 5.0 代码:
class PasswordTool:
"""
密码工具类
负责封装所有与密码强度检查相关的逻辑
"""
def __init__(self, password):
# 类的属性(静态特征)
self.password = password # 要检查的密码字符串
self.strength_level = 0 # 密码强度等级,初始为0
def process_password(self):
"""
处理密码,应用所有规则并计算最终强度等级
"""
# 规则1:密码长度大于8
if len(self.password) >= 8:
self.strength_level += 1
else:
print('密码长度要求至少8位!')
# 规则2:包含数字
if self.check_number_exist():
self.strength_level += 1
else:
print('密码要求包含数字!')
# 规则3:包含字母
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(): # isnumeric() 判断字符是否为数字
has_number = True
break
return has_number
def check_letter_exist(self):
"""
判断字符串中是否含有字母
"""
has_letter = False
for c in self.password:
if c.isalpha(): # isalpha() 判断字符是否为字母
has_letter = True
break
return has_letter
class PasswordTool:
"""
密码工具类
负责封装所有与密码强度检查相关的逻辑
"""
def __init__(self, password):
# 类的属性(静态特征)
self.password = password # 要检查的密码字符串
self.strength_level = 0 # 密码强度等级,初始为0
def process_password(self):
"""
处理密码,应用所有规则并计算最终强度等级
"""
# 规则1:密码长度大于8
if len(self.password) >= 8:
self.strength_level += 1
else:
print('密码长度要求至少8位!')
# 规则2:包含数字
if self.check_number_exist():
self.strength_level += 1
else:
print('密码要求包含数字!')
# 规则3:包含字母
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(): # isnumeric() 判断字符是否为数字
has_number = True
break
return has_number
def check_letter_exist(self):
"""
判断字符串中是否含有字母
"""
has_letter = False
for c in self.password:
if c.isalpha(): # isalpha() 判断字符是否为字母
has_letter = True
break
return has_letter
def main():
"""
主函数
"""
try_times = 5
while try_times > 0:
# 原程序用 input() 让用户输入密码,这里用固定值代替
password = 'MyPass123' # 你可以改成 '123'、'abc'、'short' 等测试
# 1. 实例化密码工具对象:创建我们的"工具箱"
password_tool = PasswordTool(password)
# 2. 使用工具箱:调用处理方法
password_tool.process_password()
# 3. 获取结果并判断
if password_tool.strength_level == 3:
print('恭喜!密码强度合格!')
break
else:
print('密码强度不合格!')
try_times -= 1
print() # 打印空行
if try_times <= 0:
print('尝试次数过多,密码设置失败!')
# 运行主程序
main()恭喜!密码强度合格!运行过程解析:
password_tool = PasswordTool(password):这行代码就是实例化。它根据PasswordTool这个“设计图”,创建了一个具体的、属于当前密码'MyPass123'的工具对象password_tool。同时,__init__方法被自动调用,完成了属性初始化。password_tool.process_password():我们告诉这个工具对象:“开始处理你的密码吧!” 对象内部就会运行三条规则,并计算出strength_level。password_tool.strength_level:处理完成后,我们直接询问对象:“你的强度等级是多少?” 然后根据结果做出判断。
面向对象的核心优势——封装: 看看现在的主程序,你是不是完全不用关心“怎么检查数字”、“怎么检查字母”了?你只需要知道:
- 用
PasswordTool(密码)创建一个工具。 - 调用工具的
process_password()方法。 - 查看工具的
strength_level属性。
至于工具内部是怎么实现的,你可以不关心(如果想了解,当然可以看类的代码)。这种“隐藏内部细节,只暴露使用接口”的思想,就叫做封装。它让代码模块化,让协作变简单(别人给你一个类,你拿来就用),也让程序更容易维护。
📝 动手练一练
- 【理解与修改】 我们当前的
PasswordTool类在process_password方法中,无论密码是否合格,都会把结果写入文件。如果我们想只在密码合格时才记录,应该修改哪部分代码?是修改主程序,还是修改PasswordTool类?为什么?
👉 点击查看参考答案
思路:这个需求是关于“何时进行记录”的业务逻辑,属于程序流程控制的一部分,而不是密码工具本身的核心功能(检查强度)。因此,应该修改主程序。
关键代码片段修改(在主程序 main 函数内):
# ... 实例化 password_tool 和调用 process_password() 之后 ...
if password_tool.strength_level == 3:
print('恭喜!密码强度合格!')
# 只有合格时才写入文件
f = open('password_v5.txt', 'a')
f.write(f'密码:{password}, 强度:{password_tool.strength_level}\n')
f.close()
break
else:
print('密码强度不合格!')
try_times -= 1
# 注意:原来在判断条件之前的那行写文件代码需要移除这样修改后,文件操作这个“行为”的发生时机就由主程序的业务逻辑来决定了,PasswordTool 类只专注于“计算强度”这一件事,职责更清晰。
- 【动手实现】 尝试为
PasswordTool类增加一条新的密码规则:密码必须同时包含大写和小写字母。你需要添加一个新的检查方法(例如check_upper_lower_exist),并在process_password方法中调用它。提示:可以使用字符串的.isupper()和.islower()方法。
👉 点击查看参考答案
思路:首先在类中添加一个新的检查方法,遍历密码,分别记录是否遇到过大写字母和小写字母。然后在 process_password 中调用该方法,并根据结果更新强度等级。
关键代码片段(添加到 PasswordTool 类中):
def check_upper_lower_exist(self):
"""
判断字符串中是否同时包含大写和小写字母
"""
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:
break
return has_upper and has_lower
# 在 process_password 方法中,在规则3之后添加规则4
def process_password(self):
# ... 规则1, 2, 3 的代码保持不变 ...
# 规则3之后:
# 规则4:同时包含大小写字母
if self.check_upper_lower_exist():
self.strength_level += 1
else:
print('密码要求同时包含大小写字母!')注意:添加新规则后,合格的 strength_level 就变成了 4,主程序中判断合格的条件也需要相应修改为 == 4。
本章小结
恭喜!你刚刚完成了编程思维的一次重要升级——从面向过程迈向了面向对象。你不仅学会了两个核心概念(类和对象),还亲手打造了一个结构清晰的 PasswordTool 类,体验了封装带来的整洁与便利。
面向对象编程是构建中大型程序的基石。虽然我们只是初窥门径,但你已经掌握了最核心的思想:将数据和操作数据的方法捆绑在一起,形成一个独立的、易于使用的“对象”。
📋 行动清单
- 运行本节代码,尝试输入不同的密码(如
‘123’、‘abcdefgh’、‘12345678’、‘MyPass123’),观察PasswordTool是如何工作的。 - 修改
PasswordTool类,比如改变某条规则的提示信息,或者调整强度等级的计算方式,感受一下修改被“封装”起来的代码是多么集中和方便。 - 思考一下,你生活中还有哪些事物可以抽象成“类”?比如“手机”类有什么属性(品牌、型号、颜色)和行为(打电话、拍照、上网)?
在下一节,我们将继续巩固面向对象的写法,把“文件读写”这个功能也封装成一个类,让我们的密码管理程序变得更加模块化和强大。
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。
- 下载第7章代码包:判断密码强弱(含全部版本 6 个 .py)ZIP · 5KB