1当程序运行时,变量可能是保存数据的最好方式 但当程序结束时,变量就会消失。为了保存数据,我们需要将数据保存到文件中。Python 提供了内置的文件对象,可以用来读写文件。
1. / 和 \的区别
在 Python 中,文件路径可以使用 /
或 \
作为路径分隔符。但是,由于 \
是转义字符,所以在字符串中需要使用 \\
来表示一个反斜杠。例如:
# 使用 / 作为路径分隔符
file_path = '/path/to/file'
# 使用 \ 作为路径分隔符,需要使用双反斜杠
file_path = 'C:\\path\\to\\file'
在 Windows 系统中,文件路径通常使用 \
作为路径分隔符。在 Unix 和 Linux 系统中,文件路径通常使用 /
作为路径分隔符。因此,为了使代码在不同操作系统上都能正常运行,建议使用 /
作为路径分隔符。
2. 修改文件路径
import os
print('当前工作路径: ' + os.getcwd())
os.chdir('C:\\Windows\\System32')
print(os.getcwd())
3. 相对路径与绝对路径
相对路径是指相对于当前工作目录的路径。绝对路径是指从根目录开始的完整路径。
例如,假设当前工作目录是 /home/user
,那么:
- 相对路径
file.txt
表示/home/user/file.txt
。 - 绝对路径
/home/user/file.txt
表示/home/user/file.txt
。
相对路径开始处的.\是可选的。例如,.\spam.txt 和 spam.txt 指的是同一个文件。
4. 用os.mkdir创建文件夹
import os
os.makedirs('D:\\Users\\Administrator\\Desktop\\test')
5.处理相对路径和绝对路径
os.path 模块提供了一些函数,返回一个相对路径的绝对路径,以及检查给定的路径是否为绝对路径。
- 调用 os.path.abspath(path)将返回参数的绝对路径的字符串。这是将相对路径转换为绝对路径的简便方法。
- 调用 os.path.isabs(path),如果参数是一个绝对路径,就返回 True,如果参数是一个相对路径,就返回 False。
- 调用 os.path.relpath(path, start)将返回从 start 路径到 path 的相对路径的字符串。如果没有提供 start,就使用当前工作目录作为开始路径。
在交互式环境中尝试以下函数:
6.查看文件大小和文件夹内容
一旦有办法处理文件路径,就可以开始搜集特定文件和文件夹的信息。os.path 模块提供了一些函数,用于查看文件的字节数以及给定文件夹中的文件和子文件夹。
- 调用 os.path.getsize(path)将返回 path 的大小(以字节为单位)的整数。
- 调用 os.listdir(path)将返回 path 下的文件和文件夹名字符串组成的列表。如果没有提供 path,就使用当前工作目录作为路径。
在交互式环境中尝试以下函数:
import os
os.path.getsize('D:\\福富')/(1024**3)
os.listdir('D:\\福富')
os.path.getsize() 函数返回的是文件或目录的大小,但它只计算了目录中直接包含的文件的大小,不包括子目录中的文件。因此,如果你传递给 os.path.getsize() 的路径是一个目录,它返回的大小可能会小于 Windows 资源管理器中右键属性查看的大小,因为资源管理器计算的是整个目录树的大小,包括所有子目录中的文件。
如果你需要计算整个目录树的大小,你需要递归地遍历目录并累加所有文件的大小。以下是一个示例代码,展示如何递归地计算目录树的大小:
import os
def get_dir_size(start_path):
total_size = 0
for dirpath, dirnames, filenames in os.walk(start_path):
for f in filenames:
fp = os.path.join(dirpath, f)
# 跳过如果是链接
if not os.path.islink(fp):
total_size += os.path.getsize(fp)
return total_size
# 目录路径
dir_path = 'D:\\福富'
# 获取目录大小(字节)
dir_size_bytes = get_dir_size(dir_path)
# 将字节转换为 GB
dir_size_gb = dir_size_bytes / (1024 ** 3)
print(f"目录大小: {dir_size_gb:.2f} GB")
这段代码定义了一个 get_dir_size()
函数,它接受一个目录路径作为参数,并返回该目录及其所有子目录的大小(以字节为单位)。然后,它将目录大小转换为 GB 并打印出来。
walk函数还是得多用用 感觉挺牛逼的
7.遍历目录树
os.walk(path)函数生成目录树下的所有文件名,可以用来遍历目录树。它对于查找特定扩展名的文件或生成目录内容的报告很有用。os.walk 通过在目录树中游走输出在目录中的文件名,向上或者向下。
os.walk() 函数会生成目录树下的所有文件名,可以用来遍历目录树。它对于查找特定扩展名的文件或生成目录内容的报告很有用。os.walk 通过在目录树中游走输出在目录中的文件名,向上或者向下。
os.walk() 函数的返回值是一个生成器,它会生成一个三元组 (dirpath, dirnames, filenames)。其中:
- dirpath 是一个字符串,表示当前正在遍历的目录的路径。
- dirnames 是一个列表,包含当前目录下的所有子目录的名字(不包括路径)。
- filenames 是一个列表,包含当前目录下的所有非目录文件的名字(不包括路径)。
os.walk() 函数会递归地遍历目录树,即它会遍历当前目录及其所有子目录。在遍历过程中,它会先处理当前目录,然后处理当前目录的子目录。
以下是一个使用 os.walk() 函数的示例,它会遍历指定目录及其所有子目录,并打印出所有文件的名字:
import os
def print_files_in_directory(directory):
for dirpath, dirnames, filenames in os.walk(directory):
for filename in filenames:
print(os.path.join(dirpath, filename))
print_files_in_directory('D:\\福富')
这段代码会遍历指定目录及其所有子目录,并打印出所有文件的名字。os.path.join() 函数用于将目录路径和文件名拼接成完整的文件路径。
listdir()函数只返回当前目录下的文件和文件夹的名字,不返回子目录中的文件和文件夹的名字。如果你需要遍历子目录,你需要使用 os.walk() 函数。
8.文件对象
文件对象是 Python 内置的文件对象,可以用来读写文件。文件对象可以通过 open() 函数创建,也可以通过 with open() 语句创建。
在 Python 中,读写文件有 3 个步骤:
1.调用 open()函数,返回一个 File 对象。
2.调用 File 对象的 read()或 write()方法。
3.调用 File 对象的 close()方法,关闭该文件。
# 使用 open() 函数创建文件对象
file = open('filename', 'mode')
# 使用 with open() 语句创建文件对象
with open('filename', 'mode') as file:
# 在 with 语句块中,文件对象是自动关闭的
pass
在 open() 函数中,第一个参数是文件名,第二个参数是文件模式。文件模式决定了文件的读写方式。常见的文件模式有:
- 'r':只读模式,打开文件进行读取。
- 'w':写入模式,打开文件进行写入。如果文件不存在,会创建一个新文件。如果文件存在,会清空文件内容。
- 'a':追加模式,打开文件进行追加。如果文件不存在,会创建一个新文件。
- 'x':独占创建模式,打开文件进行写入。如果文件不存在,会创建一个新文件。如果文件存在,会抛出 FileExistsError 异常。
- 'b':二进制模式,打开文件进行二进制读写。
- 't':文本模式,打开文件进行文本读写(默认模式)。
- '+':读写模式,打开文件进行读写。
文件对象提供了一些方法,可以用来读写文件。常见的文件对象方法有:
- read(size=-1):读取文件内容。size 参数指定读取的字节数,默认为 -1,表示读取整个文件。
- readline(size=-1):读取文件的一行内容。size 参数指定读取的字节数,默认为 -1,表示读取整行。
- readlines(hint=-1):读取文件的所有行内容,返回一个列表。hint 参数指定读取的最大行数,默认为 -1,表示读取所有行。
- write(s):写入字符串到文件。s 参数是要写入的字符串。
- writelines(lines):写入多行字符串到文件。lines 参数是一个字符串列表。
- seek(offset, whence=0):移动文件指针到指定位置。offset 参数是偏移量,whence 参数是参考位置,默认为 0,表示文件开头。whence 参数可以是 0、1 或 2,分别表示文件开头、当前位置和文件末尾。
- tell():返回文件指针的当前位置。
- flush():刷新文件缓冲区,将缓冲区中的数据写入文件。
- close():关闭文件。
文件对象的使用
下面是一个简单的示例,演示了如何使用文件对象读写文件:
# 打开文件
file = open('filename', 'r')
# 读取文件内容
content = file.read()
# 关闭文件
file.close()
# 打开文件
file = open('filename', 'w')
# 写入字符串到文件
file.write('Hello, world!')
# 关闭文件
file.close()
# 打开文件
file = open('filename', 'a')
# 追加字符串到文件
file.write('Hello, again!')
# 关闭文件
file.close()
读取文件内容
调用 open()将返回一个 File 对象。File 对象代表计算机中的一个文件,它只是Python 中另一种类型的值,就像你已熟悉的列表和字典。在前面的例子中,你将 File对象保存在 helloFile 变量中。现在,当你需要读取或写入该文件,就可以调用helloFile 变量中的 File 对象的方法。
import os
with open('D:\\学习成长\\python.txt','r',encoding='utf-8') as file:
print(file.read())
这段代码打开了一个名为 'D:\学习成长\python.txt' 的文件,以只读模式读取文件内容,并将内容打印到控制台。在读取文件内容后,文件对象会自动关闭,无需调用 close() 方法。
写入文件内容
import os
with open('D:\\学习成长\\python.txt','w',encoding='utf-8') as file:
file.write('Hello, world!')
这段代码打开了一个名为 'D:\学习成长\python.txt' 的文件,以写入模式写入字符串 'Hello, world!' 到文件中。在写入文件内容后,文件对象会自动关闭,无需调用 close() 方法。
注意:写入文件时,write方法 如果文件不存在,会创建一个新文件。如果文件存在,会清空文件内容。
追加文件内容
import os
with open('D:\\学习成长\\python.txt','a',encoding='utf-8') as file:
file.write('Hello, again!')
这段代码打开了一个名为 'D:\学习成长\python.txt' 的文件,以追加模式写入字符串 'Hello, again!' 到文件中。在追加文件内容后,文件对象会自动关闭,无需调用 close() 方法。
注意:追加文件时,write方法 如果文件不存在,会创建一个新文件。如果文件存在,会在文件末尾追加内容。
读取文件的一行内容
import os
with open('D:\\学习成长\\python.txt','r',encoding='utf-8') as file:
print(file.readline())
这段代码打开了一个名为 'D:\学习成长\python.txt' 的文件,以只读模式读取文件内容,并使用 readline() 方法读取文件的一行内容。readline() 方法会返回一个字符串,表示文件的一行内容。如果文件中没有更多行,readline() 方法会返回一个空字符串。
读取文件的所有行内容
with open('D:\\学习成长\\python.txt','r',encoding='utf-8') as file:
print(file.read())
这段代码打开了一个名为 'D:\学习成长\python.txt' 的文件,以只读模式读取文件内容,并使用 readlines() 方法读取文件的所有行内容。readlines() 方法会返回一个字符串列表,每个元素表示文件的一行内容。如果文件中没有更多行,readlines() 方法会返回一个空列表。
移动文件指针
import os
with open('D:\\学习成长\\python.txt','r',encoding='utf-8') as file:
file.seek(5)
print(file.read())
import os
with open('D:\\学习成长\\python.txt','r',encoding='utf-8') as file:
file.seek(5)
print(file.read())
print(file.tell())
这段代码打开了一个名为 'D:\学习成长\python.txt' 的文件,以只读模式读取文件内容,并使用 seek() 方法移动文件指针到文件的第 5 个字节处。seek() 方法接受两个参数,第一个参数是偏移量,第二个参数是参考位置。参考位置可以是 0、1 或 2,分别表示文件开头、当前位置和文件末尾。tell() 方法返回文件指针的当前位置。
刷新文件缓冲区
import os
with open('D:\\学习成长\\python.txt','w',encoding='utf-8') as file:
file.write('Hello, world!')
file.flush()
这段代码打开了一个名为 'D:\学习成长\python.txt' 的文件,以写入模式写入字符串 'Hello, world!' 到文件中,并使用 flush() 方法刷新文件缓冲区。flush() 方法将缓冲区中的数据写入文件。在写入文件内容后,文件对象会自动关闭,无需调用 close() 方法。
9 用 shelve 模块保存变量
shelve 模块可以用来保存变量到文件中,也可以从文件中读取变量。shelve 模块使用键值对的方式保存变量,键是字符串,值是任意类型的 Python 对象。
这个模块后面再研究一下
10 项目:生成随机的测验试卷文件
假如你是一位地理老师,班上有 35 名学生,你希望进行美国各州首府的一个小测验。不妙的是,班里有几个坏蛋,你无法确信学生不会作弊。你希望随机调整问题的次序,这样每份试卷都是独一无二的,这让任何人都不能从其他人那里抄袭答案。当然,手工完成这件事又费时又无聊。好在,你懂一些 Python。
下面是程序所做的事:
- 创建 35 份不同的测验试卷。
- 为每份试卷创建 50 个多重选择题,次序随机。
- 为每个问题提供一个正确答案和 3 个随机的错误答案,次序随机。
- 将测验试卷写到 35 个文本文件中。
- 将答案写到 35 个文本文件中。这意味着代码需要做下面的事:
- 将州和它们的首府保存在一个字典中。
- 针对测验文本文件和答案文本文件,调用 open()、write()和 close()。
- 利用 random.shuffle()随机调整问题和多重选项的次序。
capitals = {
'Alabama': 'Montgomery',
'Alaska': 'Juneau',
'Arizona': 'Phoenix',
'Arkansas': 'Little Rock',
'California': 'Sacramento',
'Colorado': 'Denver',
'Connecticut': 'Hartford',
'Delaware': 'Dover', 'Florida': 'Tallahassee',
'Georgia': 'Atlanta',
'Hawaii': 'Honolulu',
'Idaho': 'Boise',
'Illinois': 'Springfield',
'Indiana': 'Indianapolis',
'Iowa': 'Des Moines',
'Kansas': 'Topeka',
'Kentucky': 'Frankfort',
'Louisiana': 'Baton Rouge',
'Maine': 'Augusta',
'Maryland': 'Annapolis',
'Massachusetts': 'Boston',
'Michigan': 'Lansing',
'Minnesota': 'Saint Paul',
'Mississippi': 'Jackson',
'Missouri': 'Jefferson City',
'Montana': 'Helena',
'Nebraska': 'Lincoln',
'Nevada': 'Carson City',
'New Hampshire': 'Concord',
'New Jersey': 'Trenton'}
import random
for quiz_num in range(35):
quiz_file = open(f'D:\\学习成长\\python\\capitals\\capitals_{quiz_num + 1}.txt', 'w')
quiz_answers = open(f'D:\\学习成长\\python\\capitals\\capitals_answers_{quiz_num + 1}.txt', 'w')
quiz_file.write('Name:\n\nDate:\n\nPeriod:\n\n')
quiz_file.write((' ' * 20) + 'State Quiz (Form %s)' % (quiz_num + 1))
quiz_answers.write((' ' * 20) + 'Answers (Form %s)' % (quiz_num + 1))
states = list(capitals.keys())
random.shuffle(states)
for question_num in range(50):
state = states[question_num % len(capitals)]
correct_answer = capitals[state]
wrong_answers = list(capitals.values())
del wrong_answers[wrong_answers.index(correct_answer)]
wrong_answers = random.sample(wrong_answers, 3)
answer_options = wrong_answers + [correct_answer]
random.shuffle(answer_options)
quiz_file.write('\nState Question %s\n' % (question_num + 1))
for i in range(4):
quiz_file.write(' %s. %s\n' % (i + 1, answer_options[i]))
quiz_file.write('Your answer: ')
quiz_answers.write('%s. %s\n' % (question_num + 1, answer_options.index(correct_answer) + 1))
quiz_file.close()
quiz_answers.close()
11 实践项目
创建一个疯狂填词(Mad Libs)程序,它将读入文本文件,并让用户在该文本文件中出现 ADJECTIVE、NOUN、ADVERB 或 VERB 等单词的地方,加上他们自己的文本。例如,一个文本文件可能看起来像这样:The ADJECTIVE panda walked to the NOUN and then VERB. A nearby NOUN was
unaffected.你的程序将把文件读入一个大字符串,找出所有 ADJECTIVE、NOUN、ADVERB 或VERB 等单词,并让用户输入适当的单词来替换它们。然后,程序将打印出修改后的字符串。提示:你可以使用正则表达式(参见第 14 章)来找出要替换的单词。
import re
import os
os.makedirs('D:\\学习成长\\python\\madlibs\\', exist_ok=True)
with open('D:\\学习成长\\python\\madlibs\\madlibs.txt', 'w') as file:
file.write('The ADJECTIVE panda walked to the NOUN and then VERB. A nearby NOUN was unaffected.')
file = open('D:\\学习成长\\python\\madlibs\\madlibs.txt')
text = file.read()
file.close()
madlibs = re.sub(r'\bADJECTIVE\b', input('Enter an adjective: '), text)
madlibs = re.sub(r'\bNOUN\b', input('Enter a noun: '), madlibs)
madlibs = re.sub(r'\bADVERB\b', input('Enter an adverb: '), madlibs)
madlibs = re.sub(r'\bVERB\b', input('Enter a verb: '), madlibs)
with open('D:\\学习成长\\python\\madlibs\\madlibs_output.txt', 'w') as file:
file.write(madlibs)
编写一个程序,打开文件夹中所有的.txt 文件,查找匹配用户提供的正则表达式的所有行。结果应该打印到屏幕上。
import os
import re
os.makedirs('D:\\学习成长\\python\\regex\\', exist_ok=True)
with open('D:\\学习成长\\python\\regex\\regex.txt', 'a') as file:
file.write('The quick brown fox jumps over the lazy dog.')
file.write('\nPython is fun.')
file.write('\nI love to code in Python.')
file.write('\nPython is my favorite programming language.')
file.write('\nPython is easy to learn.')
pattern = input('Enter a regex: ')
# 读取文件内容
with open('D:\\学习成长\\python\\regex\\regex.txt', 'r') as file:
for line in file:
# 查找所有匹配的行
if re.search(pattern, line):
print(line, end='') # 打印匹配的行
注意: for循环遍历一个文件时 ,每次迭代都会返回一行文本。如果文件很大,这可能会占用大量内存。一种更高效的方法是使用文件迭代器,它一次只读取一行。例如,你可以这样写:
with open('regex.txt') as file:
for line in file:
if re.search(pattern, line):
print(line, end='')
12 小结
文件被组织在文件夹中(也称为目录),路径描述了一个文件的位置。运行在计算机上的每个程序都有一个当前工作目录,它让你相对于当前的位置指定文件路径,而
非总是需要完整路径(绝对路径)。os.path 模块包含许多函数,用于操作文件路径。你的程序也可以直接操作文本文件的内容。open()函数将打开这些文件,将它
们的内容读取为一个大字符串(利用 reae()方法),或读取为字符串的列表(利用方法 readlines())。Open()函数可以将文件以写模式或添加模式打开,分别创建新的文
本文件或在原有的文本文件中添加内容。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战