查看全课大纲(第 33 / 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 怎么读取文件里的密码?

约 10 分钟

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

上一节,我们让程序学会了“写日记”——把用户设置的密码和强度都保存到了文件里。这节,我们要让程序学会“读日记”!我们将打开那个保存密码的文件,看看里面都记了些什么,并且学会三种不同的“阅读”方法。学完这一节,你的密码管理程序就具备了完整的“读写”能力,离一个实用的小工具又近了一步!

💡 核心导读

  • 本节新增:只加一个功能——读取之前保存的密码文件。
  • 三种读法:学会 read()、readline() 和 readlines() 三种读取文件的方法,了解它们各自的“脾气”。
  • 文件遍历:如何一行一行地处理文件内容,就像翻书一样。
  • 承上启下:为下一节把相关功能“打包”成更强大的工具做铺垫。

回顾与目标:从“写”到“读”

我们的密码强度判断程序已经进化到了3.0版本,它能够:

  1. 判断密码强弱。
  2. 限制尝试次数。
  3. 把结果保存到文件(password_3.0.txt)。

现在,文件里已经存了一些“历史记录”。4.0版本的目标很单纯:把这些记录读出来,展示给我们看。这就像你有一个存钱罐,之前一直在往里存硬币(写文件),现在是时候打开它,数一数里面到底有多少钱了(读文件)。

文件操作,无论是读还是写,都遵循一个固定的“仪式”:打开 → 操作 → 关闭。上一节我们学了“写”这个操作,这节就学“读”。

打开“密码日记本”

读文件的第一步和写文件一样:打开它。我们需要告诉Python:要打开哪个文件,以及以什么模式打开。

import os

# 本节需要 password_3.0.txt(课程 resources 附件提供);为便于单独运行,先用示例数据建一份
with open('password_3.0.txt', 'w', encoding='utf-8') as f:   # 示例数据:每次运行都重建,保证输出一致
    f.write('''密码:abc123456, 强度:3
密码:hello, 强度:1
密码:P@ssw0rd, 强度:3''')
# 读取文件的基本框架:打开 -> 操作 -> 关闭
f = open('password_3.0.txt', 'r')  # 以只读('r')模式打开文件
# ... 这里进行读取操作 ...
f.close()  # 操作完毕,关闭文件

注意这里的模式是 'r',代表 read(只读)。这意味着程序只能从这个文件里读取内容,不能修改或写入新内容,这样更安全。

方法一:一口气读完——read()

第一种方法最简单粗暴:read()。它会把整个文件的内容,当作一个长长的字符串,一次性全部读出来。

让我们看看效果:

import os

# 本节需要 password_3.0.txt(课程 resources 附件提供);为便于单独运行,先用示例数据建一份
with open('password_3.0.txt', 'w', encoding='utf-8') as f:   # 示例数据:每次运行都重建,保证输出一致
    f.write('''密码:abc123456, 强度:3
密码:hello, 强度:1
密码:P@ssw0rd, 强度:3''')
# 使用 read() 方法读取文件
f = open('password_3.0.txt', 'r')

content = f.read()  # 整个文件内容变成一个字符串,存入content
print("使用 read() 方法读取的内容:")
print(content)

f.close()

运行上面的代码,输出会是:

使用 read() 方法读取的内容:
密码:abc123456, 强度:3
密码:hello, 强度:1
密码:P@ssw0rd, 强度:3

看起来和直接打开文件一样,对吧?实际上,content 这个变量里存储的是一个包含了换行符 \n 的大字符串。print() 函数遇到 \n 就会换行,所以显示出来是分行的。

read() 的特点:简单,适合文件内容不多的情况。但如果文件非常大(比如几百MB的小说),一次性读入内存可能会让程序“卡住”。

方法二:一次读一行——readline()

如果不想一口气吃成胖子,我们可以用 readline() 方法。它更“绅士”,一次只读取文件的一行内容。

每调用一次 readline(),它就往下读一行。

import os

# 本节需要 password_3.0.txt(课程 resources 附件提供);为便于单独运行,先用示例数据建一份
with open('password_3.0.txt', 'w', encoding='utf-8') as f:   # 示例数据:每次运行都重建,保证输出一致
    f.write('''密码:abc123456, 强度:3
密码:hello, 强度:1
密码:P@ssw0rd, 强度:3''')
# 使用 readline() 方法读取文件
f = open('password_3.0.txt', 'r')

line1 = f.readline()  # 读取第一行
print("第一行:", line1)

line2 = f.readline()  # 读取第二行
print("第二行:", line2)

f.close()

运行结果:

第一行: 密码:abc123456, 强度:3

第二行: 密码:hello, 强度:1

注意,每行末尾的换行符 \n 也会被读进来,所以 print 输出后会自动换行,有时会看到多余的空行。

readline() 的特点:灵活,可以控制每次只处理一行。但问题来了:如果我不知道文件有多少行,该怎么读完全部内容呢?难道要一直 readline() 下去吗?这就需要用到循环,我们稍后结合下一种方法一起看。

方法三:读成清单——readlines()

第三种方法 readlines()(注意有s)很实用。它把文件的每一行都作为一个元素,放入一个列表中(list)返回。

import os

# 本节需要 password_3.0.txt(课程 resources 附件提供);为便于单独运行,先用示例数据建一份
with open('password_3.0.txt', 'w', encoding='utf-8') as f:   # 示例数据:每次运行都重建,保证输出一致
    f.write('''密码:abc123456, 强度:3
密码:hello, 强度:1
密码:P@ssw0rd, 强度:3''')
# 使用 readlines() 方法读取文件
f = open('password_3.0.txt', 'r')

lines = f.readlines()  # 返回一个列表,每个元素是一行
print("使用 readlines() 读取,得到一个列表:")
print(lines)

f.close()

运行结果:

使用 readlines() 读取,得到一个列表:
['密码:abc123456, 强度:3\n', '密码:hello, 强度:1\n', '密码:P@ssw0rd, 强度:3']

看!lines 是一个 Python 列表。第一个元素是第一行字符串,第二个是第二行……这样,我们就把文件内容“转化”成了程序里最常用的列表结构,处理起来就非常方便了。

遍历文件:一行一行处理

拿到了列表,我们自然可以用 for 循环来遍历它,对每一行密码记录进行处理。

import os

# 本节需要 password_3.0.txt(课程 resources 附件提供);为便于单独运行,先用示例数据建一份
with open('password_3.0.txt', 'w', encoding='utf-8') as f:   # 示例数据:每次运行都重建,保证输出一致
    f.write('''密码:abc123456, 强度:3
密码:hello, 强度:1
密码:P@ssw0rd, 强度:3''')
# 遍历 readlines() 得到的列表
f = open('password_3.0.txt', 'r')

lines = f.readlines()
for line in lines:
    # 假设我们想给每行记录加个前缀
    print(f"读取到记录:{line}", end='') # end='' 是为了避免print自带的换行和行内换行符重复

f.close()
读取到记录:密码:abc123456, 强度:3
读取到记录:密码:hello, 强度:1
读取到记录:密码:P@ssw0rd, 强度:3

实际上,Python 提供了一种更简洁的写法,直接遍历文件对象本身,效果和遍历 readlines() 的列表一样:

import os

# 本节需要 password_3.0.txt(课程 resources 附件提供);为便于单独运行,先用示例数据建一份
with open('password_3.0.txt', 'w', encoding='utf-8') as f:   # 示例数据:每次运行都重建,保证输出一致
    f.write('''密码:abc123456, 强度:3
密码:hello, 强度:1
密码:P@ssw0rd, 强度:3''')
# 更简洁的遍历文件方法:直接 for line in f:
f = open('password_3.0.txt', 'r')

for line in f:
    print(f"读取到记录:{line}", end='')

f.close()
读取到记录:密码:abc123456, 强度:3
读取到记录:密码:hello, 强度:1
读取到记录:密码:P@ssw0rd, 强度:3

这两种写法是等价的,后者更优雅、更省内存(它并不是一次性把所有行读入列表,而是一种“惰性读取”)。

那么,用 readline() 怎么实现遍历呢?通常我们会用一个 while 循环,一直读直到读不到内容(返回空字符串)为止。不过对于新手,掌握 for line in f: 这种写法就足够应对大多数情况了。

整合到 4.0 版本

现在,我们把读取功能整合到主程序中。为了让代码更清晰,我们把之前版本的密码设置和保存逻辑先注释掉,专注于演示读取。

"""
    作者:小象教研组
    功能:判断密码强度 - 4.0版本 (演示读取文件)
    版本:4.0
    新增功能:读取保存密码的文件
"""
import os

# 本节需要 password_3.0.txt(课程 resources 附件提供);为便于单独运行,先用示例数据建一份
with open('password_3.0.txt', 'w', encoding='utf-8') as f:   # 示例数据:每次运行都重建,保证输出一致
    f.write('''密码:abc123456, 强度:3
密码:hello, 强度:1
密码:P@ssw0rd, 强度:3''')

def main():
    """
        主函数 (当前版本主要用于演示文件读取)
    """
    # 注释掉之前的密码设置和保存代码,专注于读
    # try_times = 5
    # while try_times > 0:
    #     ... (这里是1.0到3.0的代码)
    
    print("=== 开始读取保存的密码记录 ===")
    
    # 读取文件
    f = open('password_3.0.txt', 'r')
    
    # 方法1: 使用 read() 一次性读取
    # content = f.read()
    # print("方法1 - read():\n", content)
    
    # 方法2: 使用 readline() 逐行读取 (示例读两行)
    # line1 = f.readline()
    # line2 = f.readline()
    # print("方法2 - readline() 前两行:")
    # print(line1, end='')
    # print(line2, end='')
    
    # 方法3: 使用 for 循环遍历 (最常用)
    print("方法3 - 遍历文件内容:")
    for line in f:
        print(f"  -> {line}", end='')
    
    f.close()
    print("\n=== 读取结束 ===")

# 运行主程序
main()
=== 开始读取保存的密码记录 ===
方法3 - 遍历文件内容:
  -> 密码:abc123456, 强度:3
  -> 密码:hello, 强度:1
  -> 密码:P@ssw0rd, 强度:3
=== 读取结束 ===

运行这个程序,如果 password_3.0.txt 文件存在且有内容,你就会在控制台看到所有保存过的密码记录被整齐地打印出来。

📝 动手练一练

  1. 动手验证:运行上面的4.0版本代码,确保它能正确读出你之前运行3.0版本时保存的密码记录。如果文件不存在,程序会报错吗?试试看。(提示:错误类型是 FileNotFoundError)

  2. 小挑战:修改读取部分的代码,在打印每一条密码记录时,不显示“密码:”和“强度:”这些文字,只提取出密码本身和强度数字并打印。例如,将“密码:abc123456, 强度:3”处理成“abc123456 (强度: 3)”。

    • 提示:字符串有 .split() 方法可以按分隔符(如逗号,)切分,也可以用切片或者 .replace() 方法。
👉 点击查看第2题参考答案

思路:我们可以利用字符串的 .split() 方法,先按逗号分隔,再分别处理两部分,提取出关键信息。

import os

# 本节需要 password_3.0.txt(课程 resources 附件提供);为便于单独运行,先用示例数据建一份
with open('password_3.0.txt', 'w', encoding='utf-8') as f:   # 示例数据:每次运行都重建,保证输出一致
    f.write('''密码:abc123456, 强度:3
密码:hello, 强度:1
密码:P@ssw0rd, 强度:3''')
f = open('password_3.0.txt', 'r')  # 以只读('r')模式打开文件

# 参考答案代码片段
# 假设我们正在遍历文件,line 是其中一行,例如 "密码:abc123456, 强度:3\n"
for line in f:
    # 1. 去掉末尾的换行符
    line_clean = line.strip()
    
    # 2. 按逗号分割成两部分
    parts = line_clean.split(',')
    # parts 现在是 ['密码:abc123456', ' 强度:3']
    
    # 3. 分别提取密码和强度
    password_part = parts[0]  # '密码:abc123456'
    strength_part = parts[1]  # ' 强度:3'
    
    # 4. 去掉前缀,提取核心内容
    password = password_part.replace('密码:', '')
    strength = strength_part.replace(' 强度:', '')
    
    # 5. 按新格式打印
    print(f"{password} (强度: {strength})")

运行这段代码(需要放在打开文件的循环里),输出会变成:

abc123456 (强度: 3)
hello (强度: 1)
P@ssw0rd (强度: 3)

本章小结

恭喜!你的密码管理程序现在拥有了“记忆”功能。我们不仅能让它记住(写入)密码,还能让它回忆(读取)出来。

💡 本节要点回顾

  • 文件读取三步曲:open('文件名', 'r') -> 执行读操作 -> close()。
  • 三种读取方法:
    • f.read():全家福。整个文件变成一个字符串。
    • f.readline():单人照。一次读取一行。
    • f.readlines():集体照清单。所有行组成一个列表。
  • 遍历文件最佳实践:直接使用 for line in f:,简洁高效。

📋 行动清单

  • 运行4.0代码,亲眼看到程序读出你之前保存的密码。
  • 尝试分别取消注释代码中的 read() 和 readline() 部分,感受三种方法的不同输出。
  • 完成“动手练一练”的小挑战,练习一下字符串处理的基本操作。

我们已经把判断密码、保存、读取这些功能都实现了。但你看,main() 函数里现在有好多独立的函数(比如 check_number_exist),它们都和“密码”这件事相关。下一节,我们要玩个更酷的“打包”游戏——把这些相关的函数和数据封装成一个整体,这就是“面向对象编程”的起点。你的程序将变得更模块化、更强大!

—— 小象教研组

配套资料 · 直接下载

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

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