查看全课大纲(第 31 / 51 节)
  1. 1.为什么人人都该学点编程?
  2. 2.计算机与程序设计:你的电脑到底在“想”什么?
  3. 3.Python 这门语言,到底有什么魔力?
  4. 4.Python 开发环境配置:如何拥有你的第一个“编程工具箱”?
  5. 5.如何安装一个更强大的代码编辑器?
  6. 6.汇率兑换1.0:你的第一个“钱生钱”小程序
  7. 7.你的第一行代码,藏着哪些秘密?
  8. 8.汇率兑换2.0(上):让程序看懂“CNY”和“USD”
  9. 9.汇率兑换程序,如何让它“聪明”地判断币种?
  10. 10.汇率兑换程序能一直运行,直到我喊停吗?
  11. 11.汇率兑换4.0:如何把“算钱”功能打包成积木?
  12. 12.汇率兑换5.0:给你的程序穿上“结构化”的西装
  13. 13.怎么用 Python 画一个会动的五角星?
  14. 14.如何让程序自动画出不同大小的五角星?
  15. 15.函数自己调用自己,会发生什么?
  16. 16.用递归画出神奇的分形树
  17. 17.Python 怎么计算你一天躺着不动能消耗多少热量?
  18. 18.如何让程序“活”起来,持续为你服务?
  19. 19.如何让 BMR 计算器更“聪明”?
  20. 20.当程序遇到“不按套路出牌”的用户怎么办?
  21. 21.怎么用 Python 模拟一个“滚雪球”式的存钱计划?
  22. 22.如何用列表记录每一周的存款?
  23. 23.如何让程序自己数数?—— 用 for 循环解放你的双手
  24. 24.52周存钱挑战4.0:你的存款计算器能有多灵活?
  25. 25.52周存钱挑战:怎么根据日期自动查存款?
  26. 26.Python 怎么判断一年中的第几天?
  27. 27.列表 vs 元组:哪个更适合存储月份天数?
  28. 28.用集合给月份分个队,换个思路算天数
  29. 29.把月份和天数“锁”在一起:用字典给数据配个对
  30. 30.Python 怎么判断密码强弱?
  31. 31.Python 怎么给密码设置“防沉迷”系统?
  32. 32.Python 怎么把密码保存到文件里?
  33. 33.Python 怎么读取文件里的密码?
  34. 34.Python 怎么把密码检查工具“打包”起来?
  35. 35.Python 怎么把文件操作也“打包”起来?
  36. 36.计算机怎么“扔骰子”?——用Python模拟随机事件
  37. 37.如何用 Python 模拟掷两个骰子?
  38. 38.怎么用 Python 把骰子轨迹画出来?
  39. 39.骰子点数分布长啥样?用直方图一眼看穿!
  40. 40.用科学计算库让骰子程序“起飞”
  41. 41.空气质量指数怎么算?手把手教你写一个AQI计算器
  42. 42.空气质量指数计算:从零开始,让程序看懂空气
  43. 43.如何读取空气质量数据文件并找出空气质量最好的五个监测点?
  44. 44.JSON 数据怎么变成 Excel 表格?—— 让数据换个“马甲”
  45. 45.Python 怎么让程序自己判断文件类型?
  46. 46.如何让程序自己上网查空气质量?
  47. 47.用美味的汤来解析网页:Beautiful Soup 入门
  48. 48.如何让爬虫自动抓取全国所有城市的空气质量?
  49. 49.爬到的数据怎么存下来?—— 把全国空气质量数据保存为CSV文件
  50. 50.用 pandas 玩转空气质量数据:找出全国空气最好和最差的城市
  51. 51.空气质量数据怎么“洗”干净,还能画成图?

Python 怎么给密码设置“防沉迷”系统?

约 17 分钟

小象实战讲义 · Python 入门:8 个小项目边玩边学

在上一节,我们做出了一个能判断密码强弱的“裁判”,它会告诉你密码是“合格”还是“不合格”。但现实是,总有人想用“123456”这种弱密码蒙混过关,然后一遍又一遍地试。这太不酷了!我们的程序怎么能无限容忍这种行为呢?

所以,这一节我们要给密码设置程序加上一个 “防沉迷”系统:限制用户最多只能尝试设置5次密码。如果5次内成功了,就恭喜他;如果5次都失败了,就礼貌地请他“下次再来”。在这个过程中,我们会解锁一个控制循环的超级技能:如何优雅地“叫停”一个正在运行的循环。

💡 核心导读

  • 新增功能:为密码设置程序增加尝试次数限制(最多5次)。
  • 核心新知:学习 break 和 continue 语句,掌握如何从循环中“跳出”或“跳过”。
  • 项目迭代:在1.0版本的基础上,用 while 循环和 break 语句构建一个更健壮、更人性化的密码设置流程。

一、循环的“暂停键”与“跳过键”

想象一下,你正在一个长长的队伍里排队(一个 for 循环),突然接到一个重要电话(满足某个条件),这时你有两个选择:

  1. 直接离开队伍,不排了 → 对应 break(终止整个循环)。
  2. 接完电话,然后回到队伍里继续排,但错过了一次叫号 → 对应 continue(终止本次循环,进入下一次)。

这两个“键”是控制循环流程的关键。我们先通过两个小例子,看看它们到底怎么用。

1. break:一键清空购物车(终止整个循环)

break 就像购物时的“清空购物车”按钮,一旦按下,整个购物(循环)过程立刻结束,后面的商品(循环体)看都不看了。

# 例子:找到第一个偶数就立刻"收工"
for i in range(10):  # i 会从0遍历到9
    if i % 2 == 0:   # 如果 i 除以2的余数是0(即 i 是偶数)
        print(f"找到了第一个偶数:{i},循环终止!")
        break        # 立刻跳出整个 for 循环
    print(f"当前检查的数字是:{i}")
print("循环外的代码,break后执行到这里。")
找到了第一个偶数:0,循环终止!
循环外的代码,break后执行到这里。

发生了什么? 当 i 等于0时,它满足 i % 2 == 0 的条件,于是执行了 break。break 一声令下,整个 for 循环被强制终止,所以 print(f”当前检查的数字是:{i}”) 这句根本没有机会执行,循环也永远不会去检查 i=1, 2, 3... 了。

2. continue:跳过不喜欢的菜(终止本次循环)

continue 则像在自助餐厅取餐,看到一道不喜欢的菜(满足某个条件),你就跳过它,直接去看下一道菜,但你还是会继续取餐(循环继续)。

# 例子:只打印奇数,遇到偶数就"跳过"
for i in range(10):
    if i % 2 == 0:   # 如果 i 是偶数
        continue     # 跳过本次循环的剩余部分,直接开始下一次循环
    print(f"这是一个奇数:{i}")
print("所有奇数已打印完毕。")
这是一个奇数:1
这是一个奇数:3
这是一个奇数:5
这是一个奇数:7
这是一个奇数:9
所有奇数已打印完毕。

发生了什么? 当 i 是偶数(0, 2, 4, 6, 8)时,continue 被执行。它不会终止整个循环,而是立刻结束当前这一轮循环,循环体内 continue 后面的代码(print)被跳过,程序直接进入下一轮循环(i 加1)。所以,只有奇数被打印了出来。

一句话总结:

  • break:老板喊“下班了!”,所有人立刻离开办公室(终止整个循环)。
  • continue:你正在写代码,突然要接个电话,接完回来继续写刚才的代码(跳过本次循环剩余部分,进入下一次)。

二、优化我们的“密码裁判”

在1.0版本中,我们有两个函数 check_number_exist 和 check_letter_exist,它们会遍历密码的每一个字符。一旦找到数字或字母,其实就没必要继续检查后面的字符了,因为“包含”这个条件已经满足。

这时,break 就派上用场了!我们可以让函数“找到即止”,提高效率。

def check_number_exist(password_str):
    """
    判断字符串中是否含有数字
    一旦找到,立刻用 break 终止循环,提高效率
    """
    has_number = False
    for c in password_str:
        if c.isnumeric():  # 如果字符是数字
            has_number = True
            break  # 找到啦!后面的不用看了,跳出循环
    return has_number

def check_letter_exist(password_str):
    """
    判断字符串中是否含有字母
    一旦找到,立刻用 break 终止循环
    """
    has_letter = False
    for c in password_str:
        if c.isalpha():   # 如果字符是字母
            has_letter = True
            break  # 找到啦!跳出循环
    return has_letter

这样改的好处:如果密码是 ”A1b2c3d4”,在检查数字时,看到 ’1’ 就会立刻停止,不会再去检查后面的 ’b’, ‘2’, ‘3’…。代码变得更“聪明”了。

三、打造密码“防沉迷”系统(2.0版本核心)

现在,进入本节的重头戏:给主程序加上尝试次数限制。思路如下:

  1. 给用户5次机会(try_times = 5)。
  2. 只要机会次数大于0,就允许用户输入密码(用 while try_times > 0: 循环)。
  3. 每次输入后,判断密码强弱。
  4. 如果密码合格:恭喜用户,并用 break 终止整个 while 循环(游戏结束,成功!)。
  5. 如果密码不合格:告诉用户哪里不行,并将尝试次数减1(try_times -= 1)。
  6. 当5次机会用完(try_times 减到0),循环条件 try_times > 0 不再满足,循环自动结束。
  7. 循环结束后,判断如果 try_times <= 0,则提示用户“尝试次数过多,密码设置失败”。

下面是完整的2.0版本代码,新增的逻辑已经用注释标出:

"""
    作者:小象教研组
    功能:判断密码强度
    版本:2.0
    2.0新增功能:限制密码设置次数(最多5次),并优化循环效率
"""

def check_number_exist(password_str):
    """判断字符串中是否含有数字"""
    has_number = False
    for c in password_str:
        if c.isnumeric():
            has_number = True
            break  # 找到数字就跳出循环
    return has_number

def check_letter_exist(password_str):
    """判断字符串中是否含有字母"""
    has_letter = False
    for c in password_str:
        if c.isalpha():
            has_letter = True
            break  # 找到字母就跳出循环
    return has_letter

# ---------- 主程序开始 ----------
# 2.0 新增:设置最大尝试次数
try_times = 5

# 2.0 新增:使用 while 循环控制尝试次数
while try_times > 0:
    # 原程序这里使用 input(),为了你能直接运行,我们用一个固定密码示例
    # 你可以修改下面这行 password 的值来测试不同密码,例如:password = '123456'
    password = 'Abc12345'  # 这是一个合格的密码示例

    strength_level = 0

    # 规则1:密码长度大于8
    if len(password) >= 8:
        strength_level += 1
    else:
        print('密码长度要求至少8位!')

    # 规则2:包含数字
    if check_number_exist(password):
        strength_level += 1
    else:
        print('密码要求包含数字!')

    # 规则3:包含字母
    if check_letter_exist(password):
        strength_level += 1
    else:
        print('密码要求包含字母!')

    # 判断最终强度
    if strength_level == 3:
        print('恭喜!密码强度合格!')
        break  # 2.0 新增:合格后立即跳出 while 循环,游戏胜利!
    else:
        print('密码强度不合格!')
        try_times -= 1  # 2.0 新增:失败一次,机会减一
        print(f'剩余尝试次数:{try_times}')
        print()  # 打印一个空行,让输出更清晰

# 2.0 新增:循环结束后,判断是否因次数用尽而失败
if try_times <= 0:
    print('尝试次数过多,密码设置失败!')

运行一下看看效果:

因为我们示例密码 ’Abc12345’ 是合格的,所以程序会直接成功并跳出。

恭喜!密码强度合格!

你可以把第28行的密码改成 ’123’ 再运行一次,模拟连续失败的情况:

密码长度要求至少8位!
密码要求包含字母!
密码强度不合格!
剩余尝试次数:4

(此处会重复输出4次,每次剩余次数递减...)

密码长度要求至少8位!
密码要求包含字母!
密码强度不合格!
剩余尝试次数:0

尝试次数过多,密码设置失败!

看,我们的“防沉迷”系统生效了!程序不再是无休止的“复读机”,而是一个有规则、有反馈的智能助手。

四、项目回顾与升级清单

恭喜!你的密码强度检测工具成功升级到了2.0版本。比起1.0,它现在:

  1. 更高效:检查函数找到目标后立刻停止,不浪费计算资源。
  2. 更健壮:限制了尝试次数,防止无效的无限循环。
  3. 更友好:给出了清晰的剩余次数提示和最终失败原因。

本节新增的核心技能就是 break。我们用它做了两件事:

  • 在 for 循环中提前结束遍历。
  • 在 while 循环中,当满足成功条件时提前结束整个设置流程。

continue 这次虽然没用到,但你已经理解了它的作用,以后在需要“跳过”某些情况的循环里,它会非常有用。

📝 动手练一练

  1. break 与 continue 竞速赛:编写一个程序,计算从1加到100的和,但如果遇到数字7的倍数,就跳过不加(用 continue);如果累加和超过400,则立刻停止计算(用 break)。最后打印出停止时的数字和当前的总和。
👉 点击查看参考答案

思路:用 for 循环遍历1到100,用 sum_total 变量记录总和。在循环内,先判断是否是7的倍数(跳过),再累加,然后判断总和是否超过400(跳出)。

sum_total = 0
stop_at = 0

for num in range(1, 101):
    # 遇到7的倍数就跳过
    if num % 7 == 0:
        continue
    # 累加
    sum_total += num
    # 判断总和是否超过400
    if sum_total > 400:
        stop_at = num
        break

print(f"在累加到数字 {stop_at} 时,总和 {sum_total} 超过了400,计算停止。")
  1. 增强版“防沉迷”:当前的程序,即使用户第一次就输入了正确密码,也会显示“剩余尝试次数:5”。你能修改一下代码,让只有在密码不合格时,才显示剩余尝试次数吗?
👉 点击查看参考答案

思路:将显示剩余次数的 print 语句,从 else 块的最后一行,移动到“密码不合格”的提示信息之后,并且确保只在 try_times 减少后才显示。

# 这是需要修改的代码片段(位于 while 循环内):
if strength_level == 3:
    print('恭喜!密码强度合格!')
    break
else:
    print('密码强度不合格!')
    try_times -= 1
    # 将显示剩余次数的语句放在这里,并且判断是否还有机会
    if try_times > 0:
        print(f'剩余尝试次数:{try_times}')
    print()

这样,当最后一次尝试也失败(try_times 变为0)后,就不会显示“剩余尝试次数:0”了。

本章小结

通过这一节的迭代,你的密码小项目不仅功能更强,更重要的是,你学会了控制程序流程的关键命令。break 和 continue 是你让代码变得更“聪明”、更“高效”的左膀右臂。

📋 行动清单

  • 运行今天的2.0完整代码,分别用合格和不合格的密码测试,观察 break 如何起作用。
  • 修改代码中的示例密码,至少测试3次失败触发的“防沉迷”提示。
  • 挑战一下“动手练一练”的题目,巩固对 break 和 continue 的理解。

在下一节,我们将让这个程序不再“雁过无痕”。用户设置的好密码,我们要把它保存到文件里,就像游戏存档一样!这将涉及到Python的文件操作,又一个非常实用且酷炫的技能。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 第7章代码包:判断密码强弱(含全部版本 6 个 .py)
    ZIP · 5KB
    下载
看图文没弄懂?展开看本节视频讲解(约 17 分钟)
📺 正在播放小象学院官方高清录播(支持倍速与清晰度调节)