Python文件关闭机制详解

Python中关闭文件很重要 首先因为受系统的限制,我们不管用哪种语言编程,都要把不在使用的文件描述符关闭,一来避免因开启文件过多导致服务异常,二来及时关闭不用的文件描述符也能节约资源。另外我们永远无法完全避免崩溃的影响,但是我们可以通过使用上下文管理器来减少崩溃带来的影响。咱们下期见!答案获取方式:已赞 已评 已关~学习更多知识与技巧,关注与私信博主(03) 阅读详情


原文转载于:http://python.jobbole.com/81477/


如果不用“with”,那么Python会在何时关闭文件呢?答案是:视情况而定。

Python程序员最初学到的东西里有一点就是可以通过迭代法很容易地遍历一个打开文件的全文:

f = open ( '/etc/passwd' )
for line in f:
     print (line)

注意上面的代码具有可行性,因为我们的文件对象“f”是一个迭代器。换句话说,“f“ 知道在一个循环或者任何其他的迭代上下文中做什么,比如像列表解析。

我的Python课堂上的大多数学生都具有其他编程语言背景,在使用以前所熟悉的语言时,他们总是在完成文件操作时被期望关闭文件。因此,在我向他们介绍了Python文件操作的内容不久后他们问起如何在Python中关闭文件时,我一点都不惊讶。

最简单的回答就是我们可以通过调用f.close()显式地关闭文件。一旦我们关闭了文件,该文件对象依然存在,但是我们无法再通过它来读取文件内容了,而且文件对象返回的可打印内容也表明文件已经被关闭。

>>> f = open ( '/etc/passwd' )
>>> f
< open file '/etc/passwd' , mode 'r' at 0x10f023270 >
>>> f.read( 5 )
'##n# '
 
f.close()
>>> f
<closed file '/etc/passwd' , mode 'r' at 0x10f023270 >
 
f.read( 5 )
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ValueError Traceback (most recent call last)
<ipython - input - 11 - ef8add6ff846> in <module>()
- - - - > 1 f.read( 5 )
ValueError: I / O operation on closed file

所以是这样,我在用Python编程的时候,很少明确地对文件调用 “close” 方法。此外,你也很可能不想或不必那样做。

打开文件的优选最佳实践方式是使用 “with” 语句,就像如下所示:

with open ( '/etc/passwd' ) as f:
     for line in f:
         print (line)

“with”语句对 “f” 文件对象调用在Python中称作“上下文管理器”的方法。也就是说,它指定 “f” 为指向 /etc/passwd 内容的新的文件实例。在 “with” 打开的代码块内,文件是打开的,而且可以自由读取。

然而,一旦Python代码从 “with” 负责的代码段退出,文件会自动关闭。试图在我们退出 “with”代码块后从 f 中读取内容会导致和上文一样的 ValueError 异常。所以,通过使用 “with”,你避免了显式地关闭文件的操作。Python 会以一种不那么有 Python 风格的方式在幕后神奇而静静地替你关闭文件。

但是你不显式地关闭文件会怎样?如果你有点懒,既不使用 “with” 代码块也不调用f.close()怎么办?这时文件会什么时候关闭?何时应该关闭文件?

我之所以问这个,是因为我教了这么多年Python,确信努力教授“with”或上下文管理器的同时又教很多其它的话题超出了学生接受的范围。在介绍性课程谈及 “with” 时,我一般会告诉学生在他们职业生涯中遇到这个问题时,让Python去关闭文件就好,不论文件对象的应用计数降为0还是Python退出时。

在我的Python文件操作免费e-mail课程中,我并没有在所有的解决方案中使用with,想看看如何。结果一些人质疑我,说不使用“with”会向人们展示一种糟糕的实践方案并且会有数据未写入磁盘的风险。

我收到了很多关于此话题的邮件,于是我问自己:如果我们没有显式地关闭文件或者没用“with”代码块,那么Python会何时关闭文件?也就是说,如果我让文件自动关闭,那么会发生什么?

我总是假定当对象的引用计数降为0时,Python会关闭文件,进而垃圾回收机制清理文件对象。当我们读文件时很难证明或核实这一点,但写入文件时却很容易。这是因为当写入文件时,内容并不会立即刷新到磁盘(除非你向“open”方法的第三个可选参数传入“False”),只有当文件关闭时才会刷新。

于是我决定做些实验以便更好地理解Python到底能自动地为我做什么。我的实验包括打开一个文件、写入数据、删除引用和退出Python。我很好奇数据是什么时候会被写入,如果有的话。

我的实验是这个样子:

f = open ( '/tmp/output' , 'w' )
f.write( 'abcn' )
f.write( 'defn' )
# check contents of /tmp/output (1)
del (f)
# check contents of /tmp/output (2)
# exit from Python
# check contents of /tmp/output (3)

我在Mac平台上用Python 2.7.9 做了第一个实验,报告显示在阶段一文件存在但是是空的,阶段二和阶段三中文件包含所有的内容。这样,在CPython 2.7中我最初的直觉似乎是正确的:当一个文件对象被垃圾回收时,它的 __del__ (或者等价的)方法会刷新并关闭文件。而且在我的IPython进程中调用“lsof”命令显示文件确实在引用对象移除后被关闭了。

那 Python3 如何呢?我在Mac上 Python 3.4.2 环境下做了以上的实验,得到了相同的结果。移除对文件对象最后的引用后会导致文件被刷新并且被关闭。

这对于 Python 2.7 和 3.4 很好。但是在 PyPy 和 Jython下的替代实现会怎样呢?或许情况会有些不同。

于是我在 PyPy 2.7.8 下做了相同的实验。而这次,我得到了不同的结果!删除文件对象的引用后——也就是在阶段2,并没有导致文件内容被刷入磁盘。我不得不假设这和垃圾回收机制的不同或其他在 PyPy 和 CPython中工作机制的不同有关系。但是如果你在 PyPy中运行程序,就绝不要指望仅仅因为文件对象的引用结束,文件就会被刷新和关闭。命令 lsof 显示直到Python进程退出时文件才会被释放。

为了好玩,我决定尝试一下 Jython 2.7b3. 结果Jython 表现出了和PyPy一样的行为。也就是说,从 Python 退出确实会确保缓存中的数据写入磁盘。

我重做了这些实验,但是我把 “abcn”和 “defn”换成了 “abcn”*1000 和“defn”*1000.

在 Python 2.7 的环境下,“abcn” * 1000 语句执行后没有任何东西写入。但“defn” * 1000 语句执行后,文件包含有4096个字节——可能代表缓冲区的大小。调用 del(f) 删除文件对象的引用导致数据被刷入磁盘和文件关闭,此时文件中共有8000字节的数据。所以忽略字符串大小的话 Python 2.7 的行为表现基本相同。唯一不同的是如果超出了缓冲区的大小,那么一些数据将在最后文件关闭数据刷新前写入磁盘。

换做是Python 3的话,情况就有些不同了。f.write执行后没有任何数据会写入。但是文件对象引用一旦结束,文件就会刷新并关闭。这可能是缓冲区很大的缘故。但毫无疑问,删除文件对象引用会使文件刷新并关闭。

至于 PyPy 和 Jython,对大文件和小文件的操作结果都一样:文件在 PyPy 或 Jython 进程结束的时候刷新并关闭,而不是在文件对象的引用结束的时候。

为了再次确认,我又使用 “with” 进行了实验。在所有情况下,我们都能够轻松的预测文件是何时被刷新和关闭的——就是当退出代码段,并且上下文管理器在后台调用合适方法的时候。

换句话说,如果你不使用“with”,那么至少在非常简单的情形下,你的数据不一定有丢失的危险。然而你还是不能确定数据到底是在文件对象引用结束还是程序退出的时候被保存的。如果你假定因为对文件唯一的引用是一个本地变量所以文件在函数返回时会关闭,那么事实一定会让你感到吃惊。如果你有多个进程或线程同时对一个文件进行写操作,那么你真的要非常小心了。

或许这个行为可以更好地定义不就可以在不同的平台上表现得基本一致了吗?也许我们甚至可以看看Python规范的开始,而不是指着CPython说“Yeah,不管版本如何总是对的”。

我依然觉得“with”和上下文管理器很棒。而且我想对于Python新手,理解“with”的工作原理很难。但我还是不得不提醒新手开发者注意:如果他们决定使用Python的其他可选版本,那么会出现很多不同于CPython的古怪情况而且如果他们不够小心,甚至会深受其害。

如果你喜欢这篇文章内容,那么不妨看看我的关于Python文件操作的 free e-mail course 或者我的电子书,“Practice Makes Python”,其中包含50个经过实际测试的Python编程练习。


PyCharm测试功能太烦人?3种方法彻底关闭自动检测(附避坑指南) 本文针对PyCharm自动检测测试文件带来的干扰,提供了三种彻底关闭该功能的实用方法:全局禁用、项目级精准调控以及通过文件命名与目录结构进行物理隔离。每种方法均附有详细的避坑指南,帮助开发者根据个人开发、团队协作等不同场景,有效管理IDE行为,提升编码效率。 阅读详情

相关推荐

OCEAN 电路仿真

介绍利用 Cadence OCEAN 进行电路脚本仿真的方法

weixin_43249158的博客 4401

Python 文件操作

1、文本与二进制文件 文本文件 打开记事本就可以阅读的文件 优点:输出内容友好,不需要手动转换 缺点: 一个字符占一个字节,文件占用的存储空间较多,读写需要转换(内存—>显示),访问时效率不高 二进制文件 这类文件将数据按照它的进制编码的形式存储。 如BMP。由 于这类文件内容是二进制编码,使用记事本打开是显然是乱码,BMP可用图片查看器解码 优点:二进制文件中的数据与数据在内存中的表现形式一致,存储数据占用空间较少,读写不需要进行转换,效率高 缺点:二进制文件无法直接以字符形式输出,必须 要经过一个

hj的博客 847

表格数据学习的图神经网络综述

今天学习一篇发表在中科院一区期刊《ACM Computing Surveys》的综述文章《Graph Neural Networks for Tabular Data Learning: A Survey with Taxonomy & Directions》,该刊主要刊载计算机理论方法领域的系统性综述与教程论文,注重跨学科技术融合研究,最新的影响因子为28.0。本文的目的在于通过学习这篇文章,了解关于表格数据学习点图神经网络一些基础知识。

qq_41009600的博客 798

Python 文件--python拥有垃圾回收机制,为什么还需要对文件进行手动关闭?

尽管python有所谓的“垃圾回收机制”,但是对于打开的文件,在不需要的时候仍然需要使用file.close()将文件对象关闭,这是为什么呢? Python拥有垃圾回收机制,会在文件对象的引用计数降至零的时候自动关闭文件,所以在Python编程中,如果忘记关闭文件并不会造成内存泄漏。 但是这并不是说可以不用关闭文件,如果你对文件进行了写入的操作,那么你应该在完成写入之后进行文件的关闭操作。因为...

beautiful77moon的博客 855

1.5元主控搞定高精度电流电压采集?STC8G1K08+INA180A3硬件设计全解析

本文详细解析了如何利用成本仅1.5元的STC8G1K08单片机与INA180A3电流检测放大器,构建一套高精度、低成本的电流电压采集系统。文章深入剖析了硬件设计精髓,包括利用MCU内部上拉电阻直驱数码管以节省成本、INA180A3的配置与计算,以及实现高频率采集并与上位机高速通信的软件策略,为嵌入式开发中的极致性价比设计提供了完整方案。

weixin_29166013的博客 598

西瓜书第二章——模型评估与选择(十折交叉验证/查准查全F1)

第二章——模型评估与选择

xsddys的博客 951

如果文件没有close会怎样

文件如果没有close会怎样(文件编程要注意什么) 文件编程最后莫忘调用close函数关闭文件。如果不关闭文件,可能会导致文件临时数据丢失,造成文件写入失败。因为文件数据在关闭之前不保存在磁盘,而是保存在运行内存中,关闭才写入磁盘。还有文件没有关闭,会浪费系统的文件描述符的分配。 ...

weixin_45380951的博客 4090

75、CAN总线收发器共模范围扩展与抗干扰芯片选型

摘要:本文探讨了CAN总线收发器共模范围扩展与抗干扰芯片选型的关键问题。作者通过风电场的实际案例,指出共模电压超标会导致总线故障甚至芯片损坏。文章分析了不同芯片(如SN65HVD1050、TJA1043等)的共模范围特性,并提供了电路设计建议,包括正确使用共模扼流圈和终端电阻。最后强调选型时要结合实际工况,在共模范围、功耗、速度和成本之间取得平衡,普通工业现场建议选择正负36V共模范围的芯片。

2401_88858637的博客 52

python学习小知识点------python为什么要关闭文件?

主要原因有三: 1.关闭文件可以近似看作我们电脑的 "刷新" 功能,关闭文件后,文件内容才会同步至磁盘。 2.linux系统中,每个进程打开文件数量是有限的。如果不关闭,资源释放就要等到垃圾回收时完成,误事。 3.打开太多文件不关闭,有可能导致资源耗尽,无法再打开新的文件。 ...

湖水微澜 3033

AI智算-K8s如何利用IB RDMA网络加速大模型分布式训练

在AI人工智能领域,大模型的微调是提升性能不可或缺的一环。通过结合InfiniBand RDMA网络的高速互联、Kubernetes的云原生容器化部署,以及智能算力调度平台,可以打造一个高效、灵活且可扩展的分布式训练环境。

Kason_iWiki 815

微信小程序爬虫终极指南:以电商小程序抓包与逆向分析为例(最新版)

在2026年的移动互联网生态中,微信小程序已经成为电商交易的核心载体之一。据统计,超过78%的头部电商平台都推出了微信小程序版本,其用户活跃度甚至超过原生App。对于数据从业者而言,小程序端往往藏着比Web端更丰富的接口数据——包括但不限于商品详情、价格波动、用户评价、库存变化、秒杀活动信息等。与传统的Web爬虫不同,微信小程序爬虫面临着三大核心挑战无URL地址栏:无法通过浏览器直接查看网络请求wx.request封装:所有请求均通过微信原生API发起,难以直接拦截然而,

2201_76125261的博客 536

python文件无法关闭_Python文件关闭机制详解

如果不用“with”,那么Python会在何时关闭文件呢?答案是:视情况而定。Python程序员最初学到的东西里有一点就是可以通过迭代法很容易地遍历一个打开文件的全文:Python123f=open('/etc/passwd')forline inf:print(line)注意上面的代码具有可行性,因为我们的文件对象“f”是一个迭代器。换句话说,“f“ 知道在一个循环或者任何其他的迭代上下文中做什...

weixin_39926040的博客 700

解决【x2openEuler环境检查未通过——CheckRepoCurlActor不通过】问题

摘要:x2openEuler使用默认repo源时出现环境检查失败问题,原因是默认源返回308永久重定向错误。解决方法包括:1)为CentOS主机配置华为yum源;2)在x2openEuler Web界面修改为自定义可用源。具体步骤包括备份原源、下载华为源、清除缓存,并通过curl测试确认新源可用性。最终成功配置openEuler-24.03-LTS-SP1版本的repo源后,环境检查顺利通过。

提供C#相关开发 、云计算、运维测试、网络安全相关技术分享与服务,有意向可联系。 258

python如何解决文件没有关闭的情况-Python文件关闭机制详解

如果不用“with”,那么Python会在何时关闭文件呢?答案是:视情况而定。Python程序员最初学到的东西里有一点就是可以通过迭代法很容易地遍历一个打开文件的全文:Python123f=open("/etc/passwd")forline inf:print(line)注意上面的代码具有可行性,因为我们的文件对象“f”是一个迭代器。换句话说,“f“ 知道在一个循环或者任何其...

weixin_39625098的博客 2394

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

python制作程序关闭前删掉文件_Python文件关闭机制详解

原文转载于:http://python.jobbole.com/81477/如果不用“with”,那么Python会在何时关闭文件呢?答案是:视情况而定。Python程序员最初学到的东西里有一点就是可以通过迭代法很容易地遍历一个打开文件的全文:注意上面的代码具有可行性,因为我们的文件对象“f”是一个迭代器。换句话说,“f“ 知道在一个循环或者任何其他的迭代上下文中做什么,比如像列表解析。我的Pyt...

weixin_34549315的博客 367

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

测试开机启动脚本信号处理机制:优雅关闭部署指南

本文介绍了如何在星图GPU平台上自动化部署“测试开机启动脚本”镜像,以构建具备优雅关闭能力的后台服务。该镜像通过实现SIGTERM等信号处理机制,确保服务在停止前能完成数据保存与资源释放,典型应用于需要保障数据完整性的长时间运行任务,如数据处理或模型推理服务。

weixin_32925455的博客 1011

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Python快速入门专业版(四十一):Python文件操作基础:打开、关闭与文本文件读写(open()函数)

基本流程:打开(open())→ 操作(读/写)→ 关闭(推荐with语句自动关闭)。open()参数file_path:文件路径(绝对或相对)。mode:决定操作类型(r读、w写、a追加等)。encoding:文本文件必设(如utf-8),解决中文乱码。读取方法read():读取全部或指定长度。readline():逐行读取(适合大型文件)。:读取所有行到列表(适合批量处理)。写入方法write():写入单个字符串(需手动加换行符)。:批量写入字符串列表。

Pocker_Spades_A的博客 1318

Python 从入门到实战(九):文件操作(让数据持久化的 “存储管家”)

本文介绍了Python文件操作的核心概念和应用场景,重点解决内存数据持久化问题。主要内容包括:1) 文本文件基础操作,通过open()函数和with语句实现安全读写;2) 三种读取方法(read()、readline()、readlines())的适用场景;3) 写入操作的write()和writelines()方法,以及w/a模式区别。文章以学生管理系统为例,演示如何将内存数据保存到文件,实现程序重启后数据不丢失。文件操作是Python实现数据持久化的关键技术,为后续学习CSV等结构化数据处理奠定基础。

2301_76297596的博客 699

Python中with open:不关文件?等着被OSError暴揍吧

Python3 open() 函数 Python3 内置函数 Python open() 函数用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数

2603_96171993的博客 60

第六章 Python基础进阶—文件及函数进阶操作(其四)

此章节主要讲解函数的进阶用法和文件主要有:函数多返回值、函数多种传参方式、匿名函数、文件的编码、文件的读取、文件的写入、文件的追加。

2403_88453964的博客 999

python强制关闭文件_分析用Python脚本关闭文件操作的机制

如果不用“with”,那么Python会在何时关闭文件呢?答案是:视情况而定。Python程序员最初学到的东西里有一点就是可以通过迭代法很容易地遍历一个打开文件的全文:注意上面的代码具有可行性,因为我们的文件对象“f”是一个迭代器。换句话说,“f“ 知道在一个循环或者任何其他的迭代上下文中做什么,比如像列表解析。我的Python课堂上的大多数学生都具有其他编程语言背景,在使用以前所熟悉的语言时,他...

weixin_39520988的博客 768

python文件无法关闭_分析用Python脚本关闭文件操作的机制

如果不用“with”,那么Python会在何时关闭文件呢?答案是:视情况而定。Python程序员最初学到的东西里有一点就是可以通过迭代法很容易地遍历一个打开文件的全文:f = open('/etc/passwd')for line in f:print(line)注意上面的代码具有可行性,因为我们的文件对象“f”是一个迭代器。换句话说,“f“ 知道在一个循环或者任何其他的迭代上下文中做什么,比如像...

weixin_39861498的博客 160

python中关闭文件_分析用Python脚本关闭文件操作的机制

如果不用“with”,那么Python会在何时关闭文件呢?答案是:视情况而定。Python程序员最初学到的东西里有一点就是可以通过迭代法很容易地遍历一个打开文件的全文:f = open('/etc/passwd')for line in f:print(line)注意上面的代码具有可行性,因为我们的文件对象“f”是一个迭代器。换句话说,“f“ 知道在一个循环或者任何其他的迭代上下文中做什么,比如像...

weixin_39825322的博客 129

04. Python中文件流的关闭

关闭文件流,try..finally 和with语句

俗人世界 1954
上一篇: Android JNI 开发 Demo by NDK (native develop kit)
下一篇: Beta分布从入门到精通
watkins
博客等级 码龄18年 1277粉丝 246原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值