Python文件读写练习题
练习1:文件复制器
题目描述
编写一个函数,将一个文件的内容复制到另一个文件。
要求
- 函数应该接受源文件路径和目标文件路径作为参数
- 需要处理文件不存在等异常情况
- 使用
with语句确保文件正确关闭 - 支持文本文件和二进制文件的复制
示例代码
def copy_file(source_path, target_path):
"""
复制文件内容
参数:
source_path: 源文件路径
target_path: 目标文件路径
"""
try:
# 使用二进制模式打开,可以复制任何类型的文件
with open(source_path, 'rb') as source:
with open(target_path, 'wb') as target:
# 逐块读取,避免大文件占用过多内存
while True:
chunk = source.read(1024) # 每次读取1KB
if not chunk:
break
target.write(chunk)
print(f"文件复制成功:{source_path} -> {target_path}")
return True
except FileNotFoundError:
print(f"错误:源文件 {source_path} 不存在")
return False
except PermissionError:
print(f"错误:没有权限访问文件")
return False
except Exception as e:
print(f"错误:{str(e)}")
return False
# 使用示例
if __name__ == "__main__":
# 复制文本文件
copy_file("source.txt", "target.txt")
# 复制图片文件
copy_file("image.jpg", "image_copy.jpg")
进阶练习
- 添加进度显示功能
- 支持复制整个目录
- 添加文件大小比较验证
练习2:行号添加器
题目描述
编写一个程序,读取文件并在每行前添加行号,然后保存到新文件。
要求
- 读取源文件的所有行
- 在每行前添加行号(从1开始)
- 行号格式:
行号: 内容 - 将结果保存到新文件
示例代码
def add_line_numbers(source_path, target_path):
"""
为文件添加行号
参数:
source_path: 源文件路径
target_path: 目标文件路径
"""
try:
with open(source_path, 'r', encoding='utf-8') as source:
lines = source.readlines()
with open(target_path, 'w', encoding='utf-8') as target:
for line_num, line in enumerate(lines, start=1):
# 保留原行的换行符,如果行末尾没有换行符则添加
if line.endswith('n'):
target.write(f"{line_num}: {line}")
else:
target.write(f"{line_num}: {line}n")
print(f"行号添加成功:{target_path}")
return True
except FileNotFoundError:
print(f"错误:文件 {source_path} 不存在")
return False
except Exception as e:
print(f"错误:{str(e)}")
return False
# 使用示例
if __name__ == "__main__":
add_line_numbers("source.txt", "numbered.txt")
输入文件示例(source.txt)
第一行内容
第二行内容
第三行内容
输出文件示例(numbered.txt)
1: 第一行内容
2: 第二行内容
3: 第三行内容
进阶练习
- 支持自定义行号格式(如:
[001],Line 1:等) - 支持跳过空行不添加行号
- 支持指定起始行号
练习3:文件比较器
题目描述
编写一个函数,比较两个文件的内容是否相同。
要求
- 比较两个文件的内容是否完全相同
- 返回布尔值表示是否相同
- 处理文件不存在的情况
- 支持文本文件和二进制文件的比较
示例代码
import os
def compare_files(file1_path, file2_path):
"""
比较两个文件是否相同
参数:
file1_path: 第一个文件路径
file2_path: 第二个文件路径
返回:
True: 文件相同
False: 文件不同或文件不存在
"""
try:
# 检查文件是否存在
if not os.path.exists(file1_path):
print(f"错误:文件 {file1_path} 不存在")
return False
if not os.path.exists(file2_path):
print(f"错误:文件 {file2_path} 不存在")
return False
# 比较文件大小
size1 = os.path.getsize(file1_path)
size2 = os.path.getsize(file2_path)
if size1 != size2:
print(f"文件大小不同:{file1_path} ({size1} bytes) vs {file2_path} ({size2} bytes)")
return False
# 逐字节比较文件内容
with open(file1_path, 'rb') as f1:
with open(file2_path, 'rb') as f2:
while True:
chunk1 = f1.read(1024)
chunk2 = f2.read(1024)
if chunk1 != chunk2:
print("文件内容不同")
return False
if not chunk1: # 读取完毕
break
print("两个文件完全相同")
return True
except Exception as e:
print(f"错误:{str(e)}")
return False
# 使用示例
if __name__ == "__main__":
# 比较两个文件
result = compare_files("file1.txt", "file2.txt")
print(f"比较结果:{result}")
进阶练习
- 显示第一个不同的位置
- 支持忽略空白字符的比较
- 支持忽略大小写的比较(仅文本文件)
- 生成差异报告
练习4:单词计数器
题目描述
编写一个程序,统计文件中每个单词出现的次数。
要求
- 读取文件内容
- 统计每个单词的出现次数
- 忽略大小写(可选)
- 按出现次数降序排列
- 输出统计结果
示例代码
import re
from collections import Counter
def count_words(file_path, ignore_case=True):
"""
统计文件中每个单词的出现次数
参数:
file_path: 文件路径
ignore_case: 是否忽略大小写,默认True
返回:
Counter对象,包含单词及其出现次数
"""
try:
with open(file_path, 'r', encoding='utf-8') as file:
content = file.read()
# 使用正则表达式提取单词(字母、数字、下划线、连字符)
# b 表示单词边界
words = re.findall(r'b[a-zA-Z0-9_-]+b', content)
if ignore_case:
# 转换为小写进行统计
words = [word.lower() for word in words]
# 使用Counter统计
word_count = Counter(words)
return word_count
except FileNotFoundError:
print(f"错误:文件 {file_path} 不存在")
return None
except Exception as e:
print(f"错误:{str(e)}")
return None
def print_word_statistics(word_count, top_n=10):
"""
打印单词统计结果
参数:
word_count: Counter对象
top_n: 显示前N个最常见的单词
"""
if word_count is None:
return
print(f"n总共有 {len(word_count)} 个不同的单词")
print(f"总单词数:{sum(word_count.values())}")
print(f"n出现次数最多的前 {top_n} 个单词:")
print("-" * 40)
for word, count in word_count.most_common(top_n):
print(f"{word:20s} : {count:5d}")
# 使用示例
if __name__ == "__main__":
# 统计单词
word_count = count_words("text.txt", ignore_case=True)
if word_count:
# 打印统计结果
print_word_statistics(word_count, top_n=20)
# 保存结果到文件
with open("word_statistics.txt", 'w', encoding='utf-8') as output:
output.write("单词统计结果n")
output.write("=" * 40 + "n")
for word, count in word_count.most_common():
output.write(f"{word:20s} : {count:5d}n")
print("n统计结果已保存到 word_statistics.txt")
输入文件示例(text.txt)
Python is a great programming language.
Python is easy to learn and powerful.
Many developers love Python.
输出示例
总共有 12 个不同的单词
总单词数:18
出现次数最多的前 10 个单词:
----------------------------------------
python : 3
is : 2
a : 1
great : 1
programming : 1
language : 1
easy : 1
to : 1
learn : 1
and : 1
进阶练习
- 支持自定义分隔符
- 过滤停用词(如:the, a, an, is等)
- 支持统计中文字词
- 生成词云图
练习5:配置文件解析器
题目描述
编写一个程序,解析类似INI格式的配置文件。
要求
- 解析INI格式的配置文件
- 支持节(section):
[section_name] - 支持键值对:
key = value - 忽略注释行(以
#或;开头) - 忽略空行
- 提供读取配置的方法
示例代码
import re
from typing import Dict, Optional
class ConfigParser:
"""INI格式配置文件解析器"""
def __init__(self, config_path):
"""
初始化配置解析器
参数:
config_path: 配置文件路径
"""
self.config_path = config_path
self.config = {} # 存储解析后的配置
self.current_section = None
self._parse()
def _parse(self):
"""解析配置文件"""
try:
with open(self.config_path, 'r', encoding='utf-8') as file:
for line_num, line in enumerate(file, start=1):
# 去除首尾空白字符
line = line.strip()
# 跳过空行
if not line:
continue
# 跳过注释行(以#或;开头)
if line.startswith('#') or line.startswith(';'):
continue
# 匹配节(section)
section_match = re.match(r'^[(.+)]$', line)
if section_match:
section_name = section_match.group(1).strip()
self.current_section = section_name
if section_name not in self.config:
self.config[section_name] = {}
continue
# 匹配键值对
key_value_match = re.match(r'^([^=]+)=(.*)$', line)
if key_value_match:
key = key_value_match.group(1).strip()
value = key_value_match.group(2).strip()
# 如果没有节,使用默认节
if self.current_section is None:
self.current_section = 'DEFAULT'
if self.current_section not in self.config:
self.config[self.current_section] = {}
self.config[self.current_section][key] = value
else:
print(f"警告:第 {line_num} 行格式不正确:{line}")
except FileNotFoundError:
print(f"错误:配置文件 {self.config_path} 不存在")
except Exception as e:
print(f"错误:解析配置文件时出错 - {str(e)}")
def get(self, section: str, key: str, default: Optional[str] = None) -> Optional[str]:
"""
获取配置值
参数:
section: 节名
key: 键名
default: 默认值
返回:
配置值,如果不存在返回default
"""
return self.config.get(section, {}).get(key, default)
def get_section(self, section: str) -> Dict[str, str]:
"""
获取整个节的配置
参数:
section: 节名
返回:
该节的所有键值对字典
"""
return self.config.get(section, {})
def get_all_sections(self) -> list:
"""获取所有节名"""
return list(self.config.keys())
def print_config(self):
"""打印所有配置"""
print("n配置文件内容:")
print("=" * 50)
for section, items in self.config.items():
print(f"n[{section}]")
for key, value in items.items():
print(f" {key} = {value}")
# 使用示例
if __name__ == "__main__":
# 创建配置文件示例
config_content = """# 数据库配置
[database]
host = localhost
port = 3306
username = admin
password = secret123
database = mydb
# 应用配置
[application]
name = MyApp
version = 1.0.0
debug = true
log_level = INFO
# 服务器配置
[server]
host = 0.0.0.0
port = 8080
timeout = 30
"""
# 写入配置文件
with open("config.ini", 'w', encoding='utf-8') as f:
f.write(config_content)
# 解析配置文件
parser = ConfigParser("config.ini")
# 打印所有配置
parser.print_config()
# 获取特定配置
print("n" + "=" * 50)
print("获取特定配置:")
db_host = parser.get("database", "host")
db_port = parser.get("database", "port")
app_name = parser.get("application", "name")
print(f"数据库主机:{db_host}")
print(f"数据库端口:{db_port}")
print(f"应用名称:{app_name}")
# 获取整个节
print("n" + "=" * 50)
print("服务器配置:")
server_config = parser.get_section("server")
for key, value in server_config.items():
print(f" {key}: {value}")
配置文件示例(config.ini)
# 数据库配置
[database]
host = localhost
port = 3306
username = admin
password = secret123
database = mydb
# 应用配置
[application]
name = MyApp
version = 1.0.0
debug = true
log_level = INFO
# 服务器配置
[server]
host = 0.0.0.0
port = 8080
timeout = 30
输出示例
配置文件内容:
==================================================
[database]
host = localhost
port = 3306
username = admin
password = secret123
database = mydb
[application]
name = MyApp
version = 1.0.0
debug = true
log_level = INFO
[server]
host = 0.0.0.0
port = 8080
timeout = 30
==================================================
获取特定配置:
数据库主机:localhost
数据库端口:3306
应用名称:MyApp
进阶练习
- 支持嵌套节
- 支持数据类型转换(int, float, bool等)
- 支持配置验证
- 支持写入配置文件
- 支持环境变量替换
总结
这些练习题涵盖了Python文件操作的主要方面:
- 文件复制器:练习基本的文件读写操作
- 行号添加器:练习逐行处理文件内容
- 文件比较器:练习文件内容的比较和验证
- 单词计数器:练习文本处理和数据分析
- 配置文件解析器:练习复杂文本解析和数据结构
每个练习都包含了:
- 清晰的题目描述
- 完整的功能要求
- 可运行的示例代码
- 使用示例和输出示例
- 进阶练习建议
建议按照顺序完成这些练习,逐步提高文件操作的技能水平。