前几天看到,有小伙伴在问,为什么代码中打开文件有的时候用open,有的时候用with open,一会close,一会又没有close,真让人摸不着头脑。我们来看一看,这究竟是怎么回事。

Python中,open 是一个内置函数,用于打开文件进行读取、写入或其他文件操作。而 with open 则是一种使用上下文管理器来自动管理文件打开和关闭过程的语法糖,为文件操作提供了更安全、简洁的语法。

open 函数

当你直接使用 open 函数时,其基本语法如下:

file_object = open(file_path, mode='r', encoding=None, errors=None, buffering=-1, newline=None, closefd=True, opener=None)
  • • file_path:要打开的文件的路径。
  • • mode:指定打开文件的模式,如 'r' 代表只读,'w' 代表写入(会覆盖原有内容),'a' 代表追加等。
  • • encoding:指定文件的编码方式,如 'utf-8'
  • • 其他参数如 errorsbufferingnewlineclosefdopener 分别控制错误处理、缓冲策略、换行符处理等高级选项。

使用 open 函数后,你需要手动调用文件对象的 close() 方法来关闭文件,以释放系统资源。

f = open('example.txt', 'r')
content = f.read()
f.close()

这里的问题在于,如果在读写文件的过程中发生异常,可能导致 file.close() 没有被执行,从而造成文件资源未被正确释放。因此,在使用 open 函数而不借助 with 语句时,通常需要使用 try...finally 来确保文件总是会被关闭。

filename = 'example.txt'
try:
    file = open(filename, 'r')
    content = file.read()
finally:
    file.close()

with open 语句

with open 语句利用了 Python 的上下文管理协议(即实现了 __enter__ 和 __exit__ 方法的对象),它会在进入块时自动打开文件,并在离开块时(无论是否发生异常)自动调用 close 方法关闭文件。

这让代码更加简洁和安全,即使在读写过程中发生异常也是如此,这大大提高了代码的健壮性和资源管理的便捷性。

基本语法如下:

with open(file_path, mode='r', encoding=None) as file:
    # 在这里进行文件操作
    content = file.read()
# 文件在这里会自动关闭,无需调用 file.close()

举个🌰,下面是一个使用 with open 读取文件内容并打印到控制台。

# 假设我们有一个名为 example.txt 的文件,内容是我们想要读取的数据
# 文件路径根据实际情况进行调整

# 使用 with open 读取文件
with open('example.txt', 'r', encoding='utf-8') as file:
    # 逐行读取文件内容
    for line in file:
        # 打印每一行的内容
        print(line.strip())

这个例子中,example.txt 是我们假设要读取的文件名。通过 with open,我们以只读模式 ('r') 打开了这个文件,并指定了编码为 'utf-8' 来正确处理中文或其他非ASCII字符。然后,我们通过一个循环逐行读取文件内容,并使用 print 函数打印到控制台,strip() 方法用来去除每行末尾可能存在的换行符,使得输出更加整洁。当 with 代码块执行完毕后,文件自动关闭。

总结

  1. 1. 自动资源管理with open 通过 with 语句自动管理文件资源,确保文件在使用后被正确关闭,即使发生异常也不例外。而直接使用 open 需要显式调用 close(),否则可能导致文件句柄泄露。
  2. 2. 代码可读性和简洁性with open 使代码更加简洁、易读,因为不需要显式关闭文件,减少了出错的机会。
  3. 3. 异常处理:在 with 块中,如果发生了异常,finally 隐式地保证了 close() 方法的调用,这对于资源管理和错误恢复是非常重要的。

我们在写自动化代码的时候,推荐使用 with open 的方式来进行文件操作,以提高代码的安全性和可维护性。