当前位置:首页>python>Python 文件与数据库:永久存储、路径管理与重复文件查找

Python 文件与数据库:永久存储、路径管理与重复文件查找

  • 2026-10-11 08:17:00
Python 文件与数据库:永久存储、路径管理与重复文件查找

一种全新的思维方式|《Think Python》第13章

13. 文件与数据库

本章讲解如何让程序持久化保存数据,包括文件路径操作、文本读写、f-string、YAML 配置、shelve 键值数据库,以及用哈希值查找重复文件,实现从临时程序到持久程序的升级。

13.1 文件名与路径

文件被组织在目录(文件夹)中,每个程序都有当前工作目录。os 模块提供文件与目录操作函数。

import os# 获取当前工作目录os.getcwd()

运行结果:

'/home/dinsdale'
# 获取文件的绝对路径os.path.abspath('memo.txt')

运行结果:

'/home/dinsdale/memo.txt'
# 列出目录内容os.listdir('photos')

运行结果:

['digests.dat', 'digests.dir', 'notes.txt', 'new_notes.txt', 'mar-2023', 'digests.bak', 'jan-2023', 'feb-2023']
# 判断路径是否存在os.path.exists('photos')

运行结果:

True
# 判断是否为目录os.path.isdir('photos')

运行结果:

True
# 判断是否为文件os.path.isfile('photos/notes.txt')

运行结果:

True
# 跨系统拼接路径(自动适配 / 和 \)os.path.join('photos', 'jan-2023', 'photo1.jpg')

运行结果:

'photos/jan-2023/photo1.jpg'

13.2 f-strings

f-string 用于格式化字符串,可直接嵌入变量、表达式和函数调用。

num_years = 1.5num_camels = 23# 格式化输出字符串f'In {round(num_years * 12)} months I have spotted {num_camels} camels'

运行结果:

'In 18 months I have spotted 23 camels'
# 写入文件writer = open('camel-spotting-book.txt', 'w')writer.write(f'Years of observation: {num_years}\n')writer.write(f'Camels spotted: {num_camels}\n')writer.close()
# 读取文件data = open('camel-spotting-book.txt').read()print(data)

运行结果:

Years of observation: 1.5Camels spotted: 23

13.3 YAML

YAML 是人类与机器都易读的文本格式,常用于存储配置文件。

import yaml# 配置字典config = {'photo_dir': 'photos','data_dir': 'photo_info','extensions': ['jpg', 'jpeg'],}# 写入 YAML 文件config_filename = 'config.yaml'writer = open(config_filename, 'w')yaml.dump(config, writer)writer.close()
# 读取 YAML 文件reader = open(config_filename)config_readback = yaml.safe_load(reader)config_readback

运行结果:

{'data_dir': 'photo_info', 'extensions': ['jpg', 'jpeg'], 'photo_dir': 'photos'}

13.4 Shelve

shelve 提供键值数据库,像字典一样永久存储数据。

import shelve# 创建数据目录os.makedirs(config['data_dir'], exist_ok=True)# 拼接数据库路径db_file = os.path.join(config['data_dir'], 'captions')# 打开数据库(不存在则创建)db = shelve.open(db_file, 'c')
# 存入数据:键为文件路径,值为说明key = 'jan-2023/photo1.jpg'db[key] = 'Close up view of a cat nose'
# 读取数据db[key]

运行结果:

'Close up view of a cat nose'
# 遍历数据库for key in db:print(key, ':', db[key])

运行结果:

jan-2023/photo1.jpg : Close up view of a cat nose
# 关闭数据库db.close()

13.5 存储数据结构

Shelve 可以存储列表、字典等复杂结构,但修改后必须写回。

defsort_word(word):# 对单词字母排序,用于变位词分组return''.join(sorted(word))# 新建空数据库db = shelve.open('anagram_map', 'n')word = 'pots'key = sort_word(word)db[key] = [word]
# 追加单词(必须先取出、修改、再存回)word = 'tops'key = sort_word(word)anagram_list = db[key]anagram_list.append(word)db[key] = anagram_list
db[key]

运行结果:

['pots', 'tops']

13.6 检查文件是否相同

用二进制读取和 MD5 哈希判断文件内容是否一致。

# 二进制读取文件path1 = 'photos/jan-2023/photo1.jpg'data1 = open(path1, 'rb').read()type(data1)

运行结果:

bytes
# 比较两个文件内容defsame_contents(path1, path2):    data1 = open(path1, 'rb').read()    data2 = open(path2, 'rb').read()return data1 == data2
# 计算文件 MD5 哈希值import hashlibdefmd5_digest(filename):    data = open(filename, 'rb').read()    md5_hash = hashlib.md5()    md5_hash.update(data)return md5_hash.hexdigest()
md5_digest(path1)

运行结果:

'aa1d2fc25b7ae247b2931f5a0882fa37'

13.7 遍历目录

递归遍历目录与子目录,列出所有文件路径。

defwalk(dirname):for name in os.listdir(dirname):# 拼接完整路径        path = os.path.join(dirname, name)if os.path.isfile(path):# 是文件则打印print(path)elif os.path.isdir(path):# 是目录则递归进入            walk(path)
walk('photos')

运行结果:

photos/digests.datphotos/digests.dirphotos/notes.txt...photos/jan-2023/photo1.jpg

13.8 调试

处理文件时常遇到空白字符、换行符、路径大小写等问题,可用 repr 查看不可见字符。

s = '1 2\t 3\n 4'print(repr(s))

运行结果:

'1 2\t 3\n 4'

13.9 术语表

英文
中文
解释
ephemeral
临时程序
运行结束数据消失
persistent
持久程序
长期保存数据
directory
目录
存放文件与子目录
current working directory
当前工作目录
默认操作目录
path
路径
定位文件的字符串
absolute path
绝对路径
从根目录开始
relative path
相对路径
相对当前目录
f-string
格式化字符串
可嵌入表达式
configuration data
配置数据
程序设置信息
serialization
序列化
对象转字符串
deserialization
反序列化
字符串复原对象
database
数据库
高效存储数据的文件
key-value store
键值存储
类似字典的数据库
binary mode
二进制模式
按字节读取文件
hash function
哈希函数
生成内容摘要
digest
摘要
哈希结果

13.10 练习

13.10.2 替换文件内容

defreplace_all(old, new, source_path, dest_path):# 读取原文件内容    reader = open(source_path)    content = reader.read()    reader.close()# 替换字符串    new_content = content.replace(old, new)# 写入新文件    writer = open(dest_path, 'w')    writer.write(new_content)    writer.close()

13.10.3 变位词存入 Shelve

defadd_word(word, db):    key = sort_word(word)if key in db:# 已存在则追加        word_list = db[key]        word_list.append(word)        db[key] = word_listelse:# 不存在则新建列表        db[key] = [word]

最新文章

随机文章