Python中的知识点:文件操作(open函数和os模块)
文件读写
1. 文件读写基础
打开文件:
open()
函数时,除了文件名和模式,还可以指定其他参数,如buffering
(缓冲策略)、encoding
(文本编码)、errors
(编码错误处理)、newline
(换行符处理)等。'r'
:只读模式,文件必须存在。'w'
:写入模式,如果文件存在则覆盖,不存在则创建。'a'
:追加模式,如果文件存在则在文件末尾追加内容,不存在则创建。'+'
:更新模式,可以读也可以写(如'r+'
、'w+'
、'a+'
)。'b'
:二进制模式,用于处理非文本文件。file = open('example.txt', 'r', encoding='utf-8')
读取文件:
read(size=-1)
:读取整个文件内容(如果指定size
,则读取size
个字符)。
readline(size=-1)
:读取文件中的一行,如果指定size
,则读取最多size
个字符。
readlines(hint=-1)
:读取文件中的每一行,并返回一个列表,其中每个元素是一行。如果指定hint
,则读取最多hint
个字符的行数。
示例:
with open('example.txt', 'r') as file:
content = file.read() # 读取整个文件
lines = file.readlines() # 读取所有行到列表
写入文件:
write(string)
:将字符串写入文件。
writelines(lines)
:将字符串列表写入文件,不会自动添加换行符,需要手动在每个字符串末尾添加\n
。
示例:
with open('example.txt', 'w') as file:
file.write('Hello, world!\n')
file.writelines(['First line\n', 'Second line\n'])
关闭文件:
使用close()
方法显式关闭文件,但更好的做法是使用with
语句,它会在代码块执行完毕后自动关闭文件,即使在代码块中发生异常也会关闭文件。
示例:
file = open('example.txt', 'r')
try:
content = file.read()
finally:
file.close() # 使用finally确保文件关闭
或使用with
语句:
with open('example.txt', 'r') as file:
content = file.read() # 文件会在with语句结束时自动关闭
2. 编码与路径
文本编码:
encoding
参数指定编码方式,如'utf-8'
、'ascii'
、'latin1'
等。encoding
,则默认使用系统默认的编码方式(在Python 3中通常是'utf-8'
)。file = open('example.txt', 'r', encoding='utf-8')
路径:
可以使用相对路径或绝对路径指定文件位置。
在Windows中,路径分隔符为\
,但在字符串中需要转义为\\
或使用原始字符串(在字符串前加r
)。
在Unix/Linux和macOS中,路径分隔符为/
。
示例:
# Windows路径
file = open(r'C:\path\to\file.txt', 'r')
# 或
file = open('C:\\path\\to\\file.txt', 'r')
# Unix/Linux/macOS路径
file = open('/path/to/file.txt', 'r')
3. 文件夹操作
创建文件夹:
使用os.makedirs()
可以递归地创建多级目录。
使用os.mkdir()
只能创建单个目录。
示例:
import os
os.makedirs('new_directory/sub_directory') # 创建多级目录
os.mkdir('single_directory') # 创建单个目录
删除文件夹:
使用os.rmdir()
删除空目录。
使用shutil.rmtree()
删除非空目录及其内容。
示例:
import os
import shutil
os.rmdir('empty_directory') # 删除空目录
shutil.rmtree('non_empty_directory') # 删除非空目录及其内容
列出文件:
使用os.listdir()
列出指定目录下的所有文件和文件夹。
可以使用os.path.join()
来构建路径,以避免手动拼接字符串时可能出现的错误。
示例:
import os
files = os.listdir('directory_name')
for file in files:
full_path = os.path.join('directory_name', file)
print(full_path)
4. 命令行参数
使用sys.argv
可以获取命令行传递给脚本的参数列表。
sys.argv[0]
是脚本名,sys.argv[1:]
是传递给脚本的参数。
示例:
import sys
if len(sys.argv) > 1:
for arg in sys.argv[1:]:
print('Argument:', arg)
else:
print('No arguments provided.')
在命令行中运行脚本时,可以传递参数,如python script.py arg1 arg2
。
5. 数据交换格式
CSV:
使用csv
模块可以方便地读取和写入CSV文件。
可以使用csv.reader()
读取CSV文件,使用csv.writer()
写入CSV文件。
还可以使用csv.DictReader()
和csv.DictWriter()
以字典的形式处理CSV数据。
示例:
import csv
# 读取CSV文件
with open('data.csv', 'r', newline='') as file:
reader = csv.reader(file)
headers = next(reader) # 读取表头
for row in reader:
print(dict(zip(headers, row))) # 将行转换为字典
# 写入CSV文件
data = [
{'name': 'Alice', 'age': 30},
{'name': 'Bob', 'age': 25}
]
with open('output.csv', 'w', newline='') as file:
fieldnames = ['name', 'age']
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader() # 写入表头
writer.writerows(data) # 写入数据行
JSON:
使用json
模块可以将Python对象(如字典、列表)转换为JSON字符串,或将JSON字符串解析为Python对象。
示例:
import json
# 将Python对象转换为JSON字符串
data = {'name': 'Alice', 'age': 30, 'is_student': False}
json_str = json.dumps(data, indent=4) # indent参数用于美化输出
print(json_str)
# 将JSON字符串解析为Python对象
parsed_data = json.loads(json_str)
print(parsed_data)
# 将Python对象写入JSON文件
with open('data.json', 'w') as file:
json.dump(data, file, indent=4)
# 从JSON文件中读取Python对象
with open('data.json', 'r') as file:
loaded_data = json.load(file)
print(loaded_data)
6. 二进制文件
以二进制模式(如'rb'
、'wb'
)打开文件时,可以处理非文本文件(如图片、视频等)。
使用read()
和write()
方法处理字节数据。
示例:
# 写入二进制文件
data = b'\x00\x01\x02\x03\x04\x05'
with open('binary_file.bin', 'wb') as file:
file.write(data)
# 读取二进制文件
7. 异常处理与资源管理
使用try-except
块捕获文件操作中的异常,如FileNotFoundError
、IOError
、OSError
等。
使用with
语句确保文件在操作完成后正确关闭,即使发生异常也会关闭。
示例:
try:
with open('non_existent_file.txt', 'r') as file:
content = file.read()
except FileNotFoundError:
print('The file does not exist.')
except IOError as e:
print(f'An I/O error occurred: {e}')
open函数以及其返回的文件对象的方法
-
open(file, mode=‘r’, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
file
:文件路径。mode
:打开文件的模式,如 ‘r’(只读,默认),‘w’(写入,会覆盖文件),‘a’(追加),‘b’(二进制模式),‘+’(读写模式)等。buffering
:设置缓冲,-1 表示默认缓冲,0 表示无缓冲,1 表示行缓冲。encoding
:设置文件的编码。errors
:设置如何处理编码错误。newline
:控制何时写入换行符。closefd
:在打开文件时使用文件描述符,如果为 True,则在文件关闭时也会关闭文件描述符。opener
:自定义打开文件的方式。-
read(size)
- 从文件中读取指定数量的字符。如果未指定或为负数,则读取整个文件。
-
readline(size)
- 读取文件的一行,包括行尾的换行符。
size
参数指定了要读取的最大字符数。 -
readlines(hint)
- 读取所有行并返回一个列表,其中每个元素是文件的一行。
-
write(string)
- 将字符串写入文件。
-
writelines(sequence)
- 将字符串序列写入文件,不会在序列的每个元素后添加新行。
-
seek(offset, whence=0)
- 移动文件的读写指针到指定位置。
whence
参数指定了偏移量的位置:0 表示文件开始,1 表示当前位置,2 表示文件末尾。 -
tell()
- 返回当前文件指针的位置。
-
truncate(size=None)
- 截断文件到指定的大小。如果
size
参数未指定或为负数,则文件大小被设置为当前文件指针的位置。 -
flush()
- 刷新文件的缓冲区,确保所有缓冲的数据都被写入文件。
-
close()
- 关闭文件并释放系统资源。关闭后,文件不能再进行读写操作。
-
isatty()
- 检查文件是否是终端。
-
fileno()
- 返回文件的文件描述符。
-
close()
- 关闭文件对象,释放与文件对象相关的所有系统资源。一旦文件被关闭,文件对象不能再被用来进行任何文件操作,如读取或写入。如果文件是以写入模式打开的,关闭文件之前会刷新缓冲区,确保所有未写入的数据都被写入到文件中。
- 在使用
with
语句时,文件会在with
块结束时自动关闭,因此不需要显式调用close()
方法。
示例:
f = open('example.txt', 'r')
content = f.read(10) # 使用 read 方法
f.close() # 显式关闭文件
使用 with
语句自动管理文件的打开和关闭:
with open('example.txt', 'r') as f:
content = f.read(10) # 使用 read 方法
# 文件在 with 块结束时自动关闭
在第二种示例中,使用 with
语句可以确保文件在完成操作后自动关闭,即使在读取文件时发生异常也是如此。
以下是一些不同模式的练习和参考答案:
练习 1: 只读模式 (‘r’)
# 练习
with open('example.txt', 'r') as file:
content = file.read()
print(content)
# 标准答案
# 假设 example.txt 文件存在,并且包含文本 "Hello, World!"
# 输出: Hello, World!
练习 2: 写入模式 (‘w’)
# 练习
with open('example.txt', 'w') as file:
file.write('New content')
# 标准答案
# 如果 example.txt 文件存在,它将被覆盖为 "New content"
# 如果 example.txt 文件不存在,将创建一个新文件,并写入 "New content"
练习 3: 追加模式 (‘a’)
# 练习
with open('example.txt', 'a') as file:
file.write(' More content')
# 标准答案
# 假设 example.txt 文件存在,并且包含文本 "New content"
# 输出: New content More content
# 如果 example.txt 文件不存在,将创建一个新文件,并写入 " More content"
练习 4: 读写模式 (‘r+’)
# 练习
with open('example.txt', 'r+') as file:
content = file.read()
print(content)
file.write(' Updated content')
# 标准答案
# 假设 example.txt 文件存在,并且包含文本 "New content More content"
# 输出: New content More content
# 文件内容将被更新为 "New content Updated content"
练习 5: 写入模式 (‘w+’)
# 练习
with open('example.txt', 'w+') as file:
file.write('New content')
file.seek(0)
content = file.read()
print(content)
# 标准答案
# 文件将被覆盖为 "New content"
# 输出: New content
练习 6: 追加模式 (‘a+’)
# 练习
with open('example.txt', 'a+') as file:
file.write(' More content')
file.seek(0)
content = file.read()
print(content)
# 标准答案
# 假设 example.txt 文件存在,并且包含文本 "New content"
# 文件内容将被更新为 "New content More content"
# 输出: New content More content
练习 7: 二进制只读模式 (‘rb’)
# 练习
with open('example.bin', 'rb') as file:
content = file.read()
print(content)
# 标准答案
# 假设 example.bin 文件存在,并且包含二进制数据
# 输出: b'\x00\x01\x02\x03\x04\x05' (或其他二进制数据)
练习 8: 二进制写入模式 (‘wb’)
# 练习
with open('example.bin', 'wb') as file:
file.write(b'\x00\x01\x02\x03\x04\x05')
# 标准答案
# 如果 example.bin 文件存在,它将被覆盖为新的二进制数据
# 如果 example.bin 文件不存在,将创建一个新文件,并写入二进制数据
练习 9: 二进制追加模式 (‘ab’)
# 练习
with open('example.bin', 'ab') as file:
file.write(b'\x06\x07\x08\x09\x0a\x0b')
# 标准答案
# 假设 example.bin 文件存在,并且包含二进制数据
# 输出: b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b'
# 如果 example.bin 文件不存在,将创建一个新文件,并追加二进制数据
练习 10: 二进制读写模式 (‘rb+’)
# 练习
with open('example.bin', 'rb+') as file:
content = file.read()
print(content)
file.seek(0)
file.write(b'\x0c\x0d\x0e\x0f')
file.seek(0)
content = file.read()
print(content)
# 标准答案
# 假设 example.bin 文件存在,并且包含二进制数据
# 输出: b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b'
# 然后文件内容更新为: b'\x0c\x0d\x0e\x0f'
练习 11: 二进制读写模式 (‘wb+’)
# 练习
with open('example.bin', 'wb+') as file:
file.write(b'\x00\x01\x02\x03\x04\x05')
file.seek(0)
content = file.read()
print(content)
file.seek(0)
file.write(b'\x06\x07\x08\x09\x0a\x0b')
file.seek(0)
content = file.read()
print(content)
# 标准答案
# 文件将被覆盖为新的二进制数据
# 输出: b'\x00\x01\x02\x03\x04\x05'
# 然后文件内容更新为: b'\x06\x07\x08\x09\x0a\x0b'
练习 12: 二进制读写追加模式 (‘ab+’)
# 练习
with open('example.bin', 'ab+') as file:
file.write(b'\x0c\x0d\x0e\x0f')
file.seek(0)
content = file.read()
print(content)
# 标准答案
# 假设 example.bin 文件存在,并且包含二进制数据
# 输出: b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'
# 如果 example.bin 文件不存在,将创建一个新文件,并追加二进制数据
os
os模块常用功能
-
路径操作:
os.path.join(path, *paths)
:连接两个或多个路径部分,返回一个组合后的路径。os.path.exists(path)
:检查指定路径是否存在。os.path.isfile(path)
:检查路径是否为文件。os.path.isdir(path)
:检查路径是否为目录。os.path.abspath(path)
:返回路径的绝对路径。os.path.getsize(path)
:返回指定文件的大小,单位是字节。os.path.splitext(path)
:分割路径,返回文件名和扩展名。-
目录操作:
os.listdir(path='.')
:列出指定路径下的文件和目录。os.mkdir(path, mode=0o777, *, dir_fd=None)
:创建一个新目录。os.makedirs(path, mode=0o777, exist_ok=False)
:递归创建目录。os.rmdir(path)
:删除空目录。os.removedirs(name)
:递归删除目录。-
文件操作:
os.remove(path)
或os.unlink(path)
:删除文件。os.rename(src, dst)
:重命名或移动文件或目录。os.chmod(path, mode)
:改变文件的访问权限。-
环境变量:
os.environ
:一个包含所有环境变量的字典对象。-
进程管理:
os.system(command)
:执行一个命令。os.startfile(path)
:在Windows上打开一个文件或目录。-
文件描述符操作:
os.open(file, flags, mode=0o777)
:打开文件描述符。os.close(fd)
:关闭文件描述符。-
当前工作目录:
os.getcwd()
:获取当前工作目录。os.chdir(path)
:改变当前工作目录。-
系统信息:
os.name
:返回正在使用的操作系统的名称。os.uname()
:返回有关机器的详细信息。-
临时文件和目录:
os.tmpfile()
:创建一个临时文件。os.tempnam([dir], [prefix])
:创建一个临时文件名。-
符号链接:
os.symlink(source, link_name)
:创建一个符号链接。os.readlink(path)
:返回符号链接指向的目标。-
错误处理:
os_strerror(errorcode)
:返回错误码对应的错误信息。
两者的异同
联系:
-
可以一起使用:
- 在处理文件和目录时,经常需要结合使用
open()
和os
模块的功能。例如,你可以使用os
模块来改变工作目录,然后使用open()
来打开新目录中的文件。 -
都与文件系统交互:
- 两者都提供了与文件系统交互的功能,比如文件的创建、删除、读取和写入。
区别:
-
功能范围:
open()
函数主要用于打开文件,并返回一个文件对象,用于文件的读写操作。os
模块提供了更广泛的操作系统功能,包括文件和目录操作、环境变量访问、进程管理等。-
返回类型:
open()
返回一个文件对象,这个对象有一系列方法(如read()
,write()
,close()
)用于文件操作。os
模块中的函数返回的结果多种多样,取决于具体函数的功能,比如路径信息、环境变量的值、进程ID等。-
用途:
open()
通常只用于文件操作。os
模块的功能更加全面,不仅限于文件操作,还包括操作系统级别的其他功能。
作者:2301_82024007