open()函数是 Python 中用于打开文件的内置函数。它可以打开一个文件,并返回一个文件对象,以便对文件进行读取、写入、追加内容等操作。

函数语法

open(file, mode='r', buffering=-1, 
    encoding=None, errors=None, newline=None,
    closefd=True, opener=None)

参数详解

file

必要参数,要打开的文件路径和名称,可以使用相对路径或绝对路径;

# 相对路径
open('data.txt')
open('../parent/data.txt')

# 绝对路径 Windows
open(r'C:\Users\name\data.txt')
open('C:\\Users\\name\\data.txt')
open('C:/Users/name/data.txt')
# 绝对路径 WindowsLinux
open('/home/user/data.txt')

也可是文件描述符:

import os

fd = os.open('data.txt', os.O_RDONLY)
open(fd, 'r')

mode

指定打开文件的方式,如果不指定,默认为只读模式'r'

模式 描述 文件存在时 文件不存在时
'r' 只读(默认) 正常打开 抛出FileNotFoundError异常
'w' 只写 清空文件 创建新文件
'x' 独占写入 抛出FileExistsError异常 创建新文件
'a' 追加 在文件末尾追加新内容 创建新文件
'b' 二进制 与其他模式组合使用
't' 文本模式(默认) 与其他模式组合使用
'+' 读写模式 与其他模式组合使用

一些常用的例子:

# 文本模式(默认)
open('file.txt', 'r')    # 只读文本
open('file.txt', 'w')    # 只写文本
open('file.txt', 'a')    # 追加文本

# 二进制模式
open('image.jpg', 'rb')  # 读取图片
open('image.jpg', 'wb')  # 保存图片

buffering

文件缓冲的大小,默认为-1,使用系统默认值;

encoding

文件的编码方式,默认为None,表示使用系统默认的编码方式;

常见编码有:

# 常见编码
open('file.txt', 'r', encoding='utf-8')     # 最常用
open('file.txt', 'r', encoding='gbk')       # 中文Windows
open('file.txt', 'r', encoding='gb2312')    # 中文
open('file.txt', 'r', encoding='ascii')     # ASCII
open('file.txt', 'r', encoding='latin-1')  # ISO-8859-1

errors

当编码发生错误的处理方式;

# 报错
open('file.txt', 'r', encoding='utf-8', errors='strict')
# 忽略错误字符
open('file.txt', 'r', encoding='utf-8', errors='ignore')
# 替换为�或?  
open('file.txt', 'r', encoding='utf-8', errors='replace')
# 用\\xhh替换
open('file.txt', 'r', encoding='utf-8', errors='backslashreplace')

newline

文本模式下,读取或写入文件时使用的换行符。默认为None,表示使用系统默认换行符。其他可选值包括'\n''\r''\r\n'等。

closefd

是否在文件对象关闭时同时关闭文件描述符,默认为True

import os

# 获取文件描述符
fd = os.open('data.txt', os.O_RDONLY)
print(f"文件描述符: {fd}")

# 使用文件描述符 
# closefd=False,Python不会关闭这个描述符
f = open(fd, 'r', closefd=False)
content = f.read()
f.close()  # 只关闭文件对象,不关闭文件描述符

# 文件描述符仍然有效
print(f"文件描述符 {fd} 仍然有效: {os.fstat(fd)}")

# 需要手动关闭
os.close(fd)

opener

一个可调用对象,用于打开文件,默认为None;该可调用对象必须返回一个文件描述符。

import os

def custom_opener(path, flags):

    print(f"打开文件: {path}, 标志: {flags}")
    # 必须返回文件描述符
    return os.open(path, flags)

with open('test.txt', 'r', opener=custom_opener) as f:
    pass

函数返回值

open()函数返回一个文件对象,可以使用该文件对象进行文件操作,如读取文件内容、写入文件内容等。当操作完成后,需要使用close()方法关闭文件对象,以释放资源。

以下是文件对象的一些常用方法:

f = open('data.txt', 'r+', encoding='utf-8')
content = f.read()     # 读取所有内容
line = f.readline()    # 读取一行
lines = f.readlines()  # 读取所有行到列表
chunk = f.read(100)    # 读取100个字符
    
f.write('hello world!\n')    # 写入内容
f.writelines(['line1\n', 'line2\n'])  # 写入多行

position = f.tell() # 获取文件指针当前位置
f.seek(0)           # 移动到文件开头
f.seek(10)          # 移动到第10字节
f.seek(0, 2)        # 移动到文件末尾
    
f.flush()           # 将缓冲区数据写入磁盘
print(f.name)       # 文件名
print(f.mode)       # 打开模式
print(f.closed)     # 是否已关闭
print(f.encoding)   # 文件编码
f.close()           # 关闭文件对象

上下文管理器

with配合使用:

with open('test.txt', 'r') as f:
    content = f.read()
    print(content)
    # 不需要手动调用 f.close()
    # 上下文管理器会自动调用它

open() 函数示例

一次性读取整个文件:

# 不适合大文件
with open('data.txt', 'r') as f:
    content = f.read()
    print(content)

复制文件:

# 复制图片文件
with open('source.jpg', 'rb') as src:
    with open('copy.jpg', 'wb') as dst:
        dst.write(src.read())

逐块处理大文件:

# 逐块读取大文件,内存友好
CHUNK_SIZE = 1024 * 1024  # 1MB
with open('large_file.dat', 'rb') as f:
    while True:
        chunk = f.read(CHUNK_SIZE)
        if not chunk:
            break
            
        # 处理chunk...

使用迭代器逐行读取,适合大文件:

with open('data.txt', 'r') as f:
    for line in f:
        # 读的行包含换行符
        print(line.strip()) # strip() 移除首尾空白字符

向文件写入内容:

# 完全覆盖写入
with open('data.txt', 'w') as f:
    f.write('Hello, World!\n')
    f.write('第二行内容\n')
    f.writelines(['第三行\n', '第四行\n'])  # 写入多行

# 追加写入
with open('log.txt', 'a') as f:
    for i in range(10):
        f.write(f"{i}\n")

以二进制的方式,修改文件内容:

with open('test.bin', 'r+b') as f:
    # 移动文件指针到第10个字节(从0开始计数)
    f.seek(9)  
    f.write(b'X')  # 修改为字节 'X'