Python文件和异常(一)

目录

一、从文件中读取数据

(一)读取整个文件

(二)文件路径

(三)逐行读取

(四)创建一个包含文件各行内容的列表

(五)使用文件的内容

(六)包含一百万位的大型文件

(七)圆周率值中包含你的生日吗

二、写入文件

(一)写入空文件

(二)写入多行

(三)附加到文件


一、从文件中读取数据

        文本文件可存储的数据量多得难以置信:天气数据、交通数据、社会经济数据、文学作品等。每当需要分析或修改存储在文件中的信息时,读取文件都很有用,对数据分析应用程序来说尤其如此。例如,可以编写一个这样的程序:读取一个文本文件的内容,重新设置这些数据的格式并将其写入文件,让浏览器能够显示这些内容。

        要使用文本文件中的信息,首先需要将信息读取到内存中。为此,你可以一次性读取文件的全部内容,也可以以每次一行的方式逐步读取。

(一)读取整个文件

        要读取文件,需要一个包含几行文本的文件。下面首先创建一个文件,它包含精确到小数点后30位的圆周率值,且在小数点后每10位处换行:

3.1415926535 8979323846 2643383279

        要动手尝试后续示例,可在编辑器中输入这些数据行,再将文件保存为 pi_digits.txt 。

        下面的程序打开并读取这个文件,再将其内容显示到屏幕上:

with open('pi_digits.txt') as file_object:contents = file_object.read()
print(contents)

        在这个程序中,第一行代码做了大量的工作。我们先来看看函数 open() 。要以任何方式使用文件,那怕仅仅是打印其内容,都得先打开文件,才能访问它。函数 open() 接受一个参数:要打开的文件的名称。Python 在当前执行的文件所在的目录中查找指定的文件。在本例中,当前运行的是 file_reader.py ,因此 Python 在 file_reader.py 所在的目录中查找 pi_digits.txt 。函数 open() 返回一个表示文件的对象。在这里,open('pi_digits.txt') 返回一个表示文件 pi_digitls.txt 的对象, Python 将该对象赋给 file_object 供以后使用。

        关键字 with 在不再需要访问文件后将其关闭。在这个程序中,注意到我们调用了 open() ,但没有调用 close() 。也可以调用 open() 和 close() 来打开和关闭文件,但这样做时,如果程序存在 bug 导致方法 close() 未执行,文件将不会关闭。这看似微不足道,但未妥善关闭文件可能导致数据丢失或受损。如果在程序中过早调用 close() ,你会发现需要使用文件时它已关闭(无法访问),这会导致更多的错误。并非在任何情况下都能轻松确定关闭文件的怡当时机,但通过使用前面所示的结构,可让 Python 去确定:你只管打开文件,并在需要时使用它,Python 自会在合适的时候自动将其关闭。

        有了表示 pi_digits.txt 的文件对象后,使用方法 read()(前述程序的第二行)读取这个文件的全部内容,并将其作为一个长长的字符串赋给变量 contents 。这样,通过打印 contents 的值,就可将这个文本文件的全部内容显示出来:

3.1415926535 8979323846 2643383279

        相比于原始文件,该输出唯一不同的地方是末尾多了一个空行。为何会多出这个空行呢?因为 read() 到达文件未尾时返回一个空字符串,而将这个空字符串显示出来时就是一个空行。要删除多出来的空行,可在函数调用 print() 中使用 rstrip() :

with open('pi_digits.txt') as file_object:contents = file_object.read()
print(contents.rstrip())

        前面说过,Python 方法 rstrip() 删除字符串末尾的空白。现在,输出与原始文件的内容完全相同:

3.1415926535 8979323846 2643383279

(二)文件路径

        将类似于pi_digits.txt 的简单文件名传递给函数 open() 时,Python 将在当前执行的文件(即 .py 程序文件)所在的目录中查找。

        根据你组织文件的方式,有时可能要打开不在程序文件所属目录中的文件。例如,你可能将程序文件存储在了文件夹 python_work 中,而该文件夹中有一个名为 text_files 的文件夹用于存储程序文件操作的文本文件。虽然文件夹 text_files 包含在文件夹 python_work 中,但仅向 open() 传递位于前者中的文件名称也不可行,因为 Python 只在文件夹 python_work 中查找,而不会在其子文件夹 text_files 中查找。要让 Python 打开不与程序文件位于同一个目录中的文件,需要提供文件路径,让 Python 到系统的特定位置去查找。

        由于文件夹 text_files 位于文件夹 python_work 中,可以使用相对文件路径来打开其中的文件。相对文件路径让 Python 到指定的位置去查找,而该位置是相对于当前运行的程序所在目录的。例如,可这样编写代码:

with open('text_file/filename.txt') as file_object:

        这行代码让 Python 到文件夹 python_work 下的文件夹 text_files 中去查找指定的 .txt 文件。

注意:显示文件路径时,Windows 系统使用反斜杠(\)而不是斜杠(/),但在代码中依然可以使用斜杠。

        还可以将文件在计算机中的准确位置告诉 Python ,这样就不用关心当前运行的程序存储在什
么地方了。这称为绝对文件路径。在相对路径行不通时,可使用绝对路径。例如,如果 text_files 并不在文件夹 python_work 中,而在文件夹 other_files 中,则向 open() 传递路径 'text_files/filename.txt' 行不通,因为 Python 只在文件夹 python_work 中查找该位置。为明确指出希望 Python 到哪里去查找,需要提供完整的路径。 

        绝对路径通常比相对路径长,因此将其赋给一个变量,再将该变量传递给 open() 会有所帮助:

file_path = '/home/ehmatthes/other_files/text_files/filename.txt'
with open(file_path) as file_object:

        通过使用绝对路径,可读取系统中任何地方的文件。就目前而言,最简单的做法是,要么将数据文件存储在程序文件所在的目录,要么将其存储在程序文件所在目录下的一个文件夹(如 text_files )中。

注意:如果在文件路径中直接使用反斜杠,将引发错误,因为反斜杠用于对字符串中的字符进行转义。例如,对于路径 "C:\path\to\file.txt" ,其中的 \t 将被解读为制表符。如果一定要使用反斜杠,可对路径中的每个反斜杠都进行转义,如 "C:\\path\\to\\file.txt" 。

(三)逐行读取

        读取文件时,常常需要检查其中的每一行:可能要在文件中查找特定的信息,或者要以某种方式修改文件中的文本。例如,你可能要遍历一个包含天气数据的文件,并使用天气描述中包含 sunny 字样的行。在新闻报道中,你可能会查找包含标签 <headline> 的行,并按特定的格式设置它。

        要以每次一行的方式检查文件,可对文件对象使用for循环:

filename = 'pi_digits.txt'with open(filename) as file_object:for line in file_object:print(line)

        将要读取的文件的名称赋给变量 filename 。这是使用文件时的一种常见做法。变量 filename 表示的并非实际文件——它只是一个让 Python 知道到哪里去查找文件的字符串,因此可以轻松地将 'pi_digits.txt' 替换为要使用的另一个文件的名称。调用 open() 后,将一个表示文件及其内容的对象赋给了变量 file_object 。这里也使用了关键字 with ,让 Python 负责妥善地打开和关闭文件。为查看文件的内容,通过对文件对象执行循环来遍历文件中的每一行。

        打印每一行时,发现空白行更多了:

3.1415926535 8979323846 2643383279

        为何会出现这些空白行呢?因为在这个文件中,每行的末尾都有一个看不见的换行符,而函数调用 print() 也会加上一个换行符,因此每行末尾都有两个换行符:一个来自文件,另一个来自函数调用 print() 。要消除这些多余的空白行,可在函数调用 print() 中使用 rstrip() :

filename = 'pi_digits.txt'with open(filename) as file_object:for line in file_object:print(line.rstrip())

        现在,输出又与文件内容完全相同了:

3.141592653589793238462643383279

(四)创建一个包含文件各行内容的列表

        使用关键字 with 时,open() 返回的文件对象只在 with 代码块内可用。如果要在 with 代码块外访问文件的内容,可在 with 代码块内将文件的各行存储在一个列表中,并在 with 代码块外使用该列表:可以立即处理文件的各个部分,也可以推迟到程序后面再处理。

        下面的示例在 with 代码块中将文件 pi_digits.txt 的各行存储在一个列表中,再在 with 代码块外打印:

filename = 'pi_digits.txt'with open(filename) as file_object:lines = file_object.readlines()for line in lines:print(line.rstrip())

        方法 readlines() 从文件中读取每一行,并将其存储在一个列表中。接下来。该列表被赋给变量 lines 。在 with 代码块外,依然可使用这个变量。使用一个简单的 for 循环来打印 lines 中的各行。因为列表 lines 的每个元素都对应于文件中的一行,所以输出与文件内容完全一致。

(五)使用文件的内容

        将文件读取到内存中后,就能以任何方式使用这些数据了。下面以简单的方式使用圆周率的值。首先,创建一个字符串,它包含文件中存储的所有数字,且没有任何空格:

filename = 'pi_digits.txt'with open(filename) as file_object:lines = file_object.readlines()pi_string = ''
for line in lines:pi_string += line.rstrip()print(pi_string)
print(len(pi_string))

        像前一个示例一样,首先打开文件,并将其中所有的行都存储在一个列表中。创建了一个变量 pi_string ,用于指向圆周率的值。接下来,使用一个循环将各行加入 pi_string ,并删除每行末尾的换行符。打印这个字符串及其长度:

3.1415926535  8979323846  2643383279
36

        变量 pi_string 指向的字符串包含原来位于每行左边的空格,为删除这些空格,可使用 strip() 而非 Istrip() :

pi_string = ''
for line in lines:pi_string += line.strip()

        这样就获得了一个字符串,其中包含准确到30位小数的圆周率值。这个字符串长32字符,因为它还包含整数部分的3和小数点:

3.141592653589793238462643383279
32

注意:读取文本文件时,Python 将其中的所有文本都解读为字符串。如果读取的是数,并要将其作为数值使用,就必须使用函数 int() 将其转换为整数或使用函数 float() 将其转换为浮点数。

(六)包含一百万位的大型文件

        前面分析的都是一个只有三行的文本文件,但这些代码示例也可处理大得多的文件。如果我们有一个文本文件,其中包含精确到小数点后1000000位而不是30位的圆周率值,也可创建一个包含所有这些数字的字符串。为此,无须对前面的程序做任何修改,只要将这个文件传递给它即可。在这里,只打印到小数点后50位,以免终端为显示全部1000000位而不断滚动:

filename = 'pi_million_digits.txt'with open(filename) as file_object:lines = file_object.readlines()pi_string = ''
for line in lines:pi_string += line.strip()print(f"{pi_string[:52]}...")
print(len(pi_string))

        输出表明,创建的字符串确实包含精确到小数点后1000000位的圆周率值:

3.14159265358979323846264338327950288419716939937510...
1000002

        对于可处理的数据量,Python没有任何限制。只要系统的内存足够多,你想处理多少数据都可以。

(七)圆周率值中包含你的生日吗

        我一直想知道自己的生日是否包含在圆周率值中。下面来扩展刚才编写的程序,以确定某个人的生日是否包含在圆周率值的前1000000位中。为此,可将生日表示为一个由数字组成的字符串,再检查这个字符串是否包含在 pi_string 中:

filename = 'pi_million_digits.txt'with open(filename) as file_object:lines = file_object.readlines()pi_string = ''
for line in lines:pi_string += line.strip()birthday = input("Enter your birthday, in the form mmddyy: ")
if birthday in pi_string:print("Your birthday appears in the first million digits of pi!")
else:print("Your birthday does not appear in the first million digits of pi.")

        提示用户输入生日。检查这个字符串是否包含在 pi_string 中。下面来运行一下这个程序:

Enter your birthday, in the form mmddyy: 030109
Your birthday appears in the first million digits of pi!

        我的生日确实出现在了圆周率值中!读取文件的内容后,能以你能想到的任何方式对其进行分析。

二、写入文件

        保存数据的最简单的方式之一是将其写人文件中。通过将输出写人文件,即便关闭包含程序输出的终端窗口,这些输出也依然存在:可以在程序结束运行后查看这些输出,可以与别人分享输出文件,还可以编写程序来将这些输出读取到内存中并进行处理。

(一)写入空文件

        要将文本写人文件,你在调用 open() 时需要提供另一个实参,告诉 Python 你要写入打开的文件。为明白其中的工作原理,我们来将一条简单的消息存储到文件中,而不是将其打印到屏幕上:

filename = 'programming.txt'with open(filename, 'w') as file_object:file_object.write("I love programming.")

        在本例中,调用 open() 时提供了两个实参。第一个实参也是要打开的文件的名称。第二个实参 ('w') 告诉 Python ,要以写入模式打开这个文件。打开文件时,可指定读取模式 ('r') 、写入模式 ('w') 、附加模式 ('a') 或读写模式 ('r+' ) 。如果省略了模式实参,Python 将以默认的只读模式打开文件。

        如果要写入的文件不存在,函数 open() 将自动创建它。然而,以写人模式 ('w') 打开文件时千万要小心,因为如果指定的文件已经存在,Python 将在返回文件对象前清空该文件的内容。

        使用文件对象的方法 write() 将一个字符串写人文件。这个程序没有终端输出,但如果打开文件 programming.txt ,将看到其中包含如下一行内容:

I love programming.

        相比于计算机中的其他文件,这个文件没有什么不同。你可以打开它、在其中输人新文本、复制其内容、将内容粘贴到其中,等等。

注意:Python 只能将字符串写入文本文件。要将数值数据存储到文本文件中,必须先使用函数 str() 将其转换为字符串格式。

(二)写入多行

        函数 write() 不会在写人的文本末尾添加换行符,因此如果写入多行时没有指定换行符,文件看起来可能不是你希望的那样:

filename = 'programming.txt'with open(filename, 'w') as file_object:file_object.write("I love programming.")file_object.write("I love creating new games.")

        如果你打开 programming.txt ,将发现两行内容挤在一起:

I love programming.I love creating new games.

        要让每个字符串都单独占一行,需要在方法调用 write() 中包含换行符:

filename = 'programming.txt'with open(filename, 'w') as file_object:file_object.write("I love programming.\n")file_object.write("I love creating new games.\n")

        现在,输出出现在不同的行中:

I love programming.
I love creating new games.

        像显示到终端的输出一样,还可以使用空格、制表符和空行来设置这些输出的格式。

(三)附加到文件

        如果要给文件添加内容,而不是覆盖原有的内容,可以以附加模式打开文件。以附加模式打开文件时,Python 不会在返回文件对象前清空文件的内容,而是将写人文件的行添加到文件末尾。如果指定的文件不存在,Python 将为你创建一个空文件。

        下面来修改 write_message.py ,在既有文件 programming.txt 中再添加一些你酷爱编程的原因:

filename = 'programming.txt'with open(filename, 'a') as file_object:file_object.write("I also love finding meaning in large datasets.\n")file_object.write("I love creating apps that can run in a browser.\n")

        打开文件时指定了实参 'a' ,以便将内容附加到文件末尾,而不是覆盖文件原来的内容。又写人了两行,它们被添加到文件 programming.txt 末尾:

I love programming.
I love creating new games.
I also love finding meaning in large datasets.
I love creating apps that can run in a browser.

        最终的结果是,文件原来的内容还在,后面则是刚添加的内容。

未完,待续……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/700214.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

私域运营的4个核心要素

第一&#xff0c;我们要首先理解私域现在的形势。 以前私域&#xff1a;崛起的微商。发朋友圈&#xff0c;成交率高。 因为主要来源是信息差。 当代&#xff1a;信息透明化。私域流量运营的本质是获取信任。通过建立起泛人脉亲密关系。信任才重要。 第二&#xff0c;塑造一对一…

探索设计模式的魅力:状态模式揭秘-如何优雅地处理复杂状态转换

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;并且坚持默默的做事。 探索设计模式的魅力&#xff1a;状态模式揭秘-如何优雅地处理复杂状态转换 文章目录 一、案例…

VUE3使用three.js显示3D模型

使用3D模型作为自动化系统的界面已经成为潮流。尽管在AutomationML 中推荐COLLADA作为 3D 模型的标准。但是COLLADA的开发者khronos 集团却已经开发了COLLADA的后继者glTF 。glTF 2.0已经成为国际标准ISO/IEC 12113:2022。 Khronos声称-‘glTF是3D里的JPEG’。目前看来glTF 更加…

Java WEB面试系列-01

1. 什么是 Servlet? Servlet是用Java编写的服务器端程序, 其主要功能在于交互式地浏览和修改数据,生成动态Web内容。 狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,我们一般将Servlet理解为后者。 2. 为什么要使…

问题慢慢解决-通过android emulator调试android kernel-内核条件断点遇到的问题和临时解决方案

起因 在摸索到这个方案之后&#xff0c;mac m1调试aarch64 android kernel最终方案&#xff0c;就准备调试内核了&#xff0c;预备下断点的地方是 b binder_poll b ep_ptable_queue_proc b remove_wait_queue但是由于是android系统&#xff0c;上面三个函数会被频繁的触发&am…

ERC721解读

NFT(非同质化代币):类似于明朝、宋朝的青花瓷。虽然都是青花瓷。但是都具有唯一的典藏价值。而且价值可能不同。 NFT就是具有唯一价值的代币。 ERC721: 是以太坊规定实现NFT的一种标准了。实现ERC21标准的智能合约就是NFT代币了。 1.接口 1.ERC721 定义接口参考&#xff1a;ER…

vue.js中slot插槽的作用

作为一种流行的JavaScript框架&#xff0c;vue.js提供了很多功能强大的特性&#xff0c;其中之一就是插槽&#xff08;slot&#xff09;。插槽是一种能够让父组件向子组件传递内容的机制&#xff0c;它为我们构建可复用的组件提供了更大的灵活性和可扩展性。以下介绍Vue中插槽的…

《Docker极简教程》--Docker服务管理和监控--Docker服务的监控

Docker监控的必要性在于确保容器化环境的稳定性、性能和安全性。以下是几个关键原因&#xff1a; 性能优化和故障排除&#xff1a;监控可以帮助识别容器化应用程序的性能问题&#xff0c;并快速进行故障排除。通过监控关键指标&#xff0c;如CPU利用率、内存使用、网络流量等&…

ElementUI table表格组件实现双击编辑单元格失去焦点还原,支持多单元格

在使用ElementUI table表格组件时有时需要双击单元格显示编辑状态&#xff0c;失去焦点时还原表格显示。 实现思路&#xff1a; 在数据中增加isFocus:false.控制是否显示在table中用cell-dblclick双击方法 先看效果&#xff1a; 上源码&#xff1a;在表格模板中用scope.row…

springboot集成mqtt

文章目录 前言一、MQTT是什么&#xff1f;二、继承步骤1.安装MQTT2.创建项目&#xff0c;引入依赖3. 对应步骤2的代码3 测试 总结mqtt 启动后访问地址 前言 随着物联网的火热,MQTT的应用逐渐增多 曾经也有幸使用过mqtt,今天正好总结下MQTT的使用; 一、MQTT是什么&#xff1f;…

从扩散模型基础到DIT

Diffusion model 扩散模型如何工作&#xff1f; 输入随机噪声和文本内容&#xff0c;通过多次预测并去除图片中的噪声后&#xff0c;最终生成清晰的图像。 以上左边这张图&#xff0c;刚开始是随机噪声&#xff0c;999为时间序列。 为什么不直接预测下一张图片呢&#xff1f;…

springboot+vue的宠物咖啡馆平台(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

《卓有成效的管理者》

前言 管理工作在很大程度上是要言传身教的&#xff0c;如果管理者不懂得如何在自己的工作中做到卓有成效&#xff0c;就会给其他人树立错误的榜样。 第 1 章 卓有成效是可以学习的 关于体力工作&#xff0c;我们已有一套完整的衡量方法和制度&#xff0c;从工程设计到质量控制…

Java中常用的类(一)

一、API应用程序编程接口&#xff1a; API&#xff1a;指的是官方给开发人员提供的一个说明文档&#xff0c;对于语言有哪些类&#xff0c;类中有哪些方法进行说明 二、Object类 Object是java中所有类的父类&#xff0c;体系结构中最顶层的类&#xff0c;位置是java.lang.Ob…

【深度学习笔记】3_4 逻辑回归之softmax-regression

3.4 softmax回归 Softmax回归&#xff08;Softmax Regression&#xff09;&#xff0c;也称为多类逻辑回归&#xff08;Multinomial Logistic Regression&#xff09;&#xff0c;是一种用于多分类问题的分类算法。虽然名字里面带回归&#xff0c;实际上是分类。 前几节介绍的…

Socks5代理与代理IP的应用

在全球化的背景下&#xff0c;跨界电商和游戏行业正经历着蓬勃发展的时代。然而&#xff0c;随之而来的网络安全挑战也日益突出。为了应对这些挑战&#xff0c;Socks5代理与代理IP等技术成为了保障网络安全的重要工具。本文将探讨这些技术在跨界电商和游戏行业中的应用&#xf…

Python模块百科_时间的访问和转换(time)_下

TOC 一、概述 time模块提供了各种与时间相关的函数。相关功能还可以参阅datetime 和 calendar模块。 尽管所有平台皆可引用此模块&#xff0c;但模块内的函数并不是所有平台都可用。此模块中定义的大多数函数的实现都是调用其所在平台的C语言库的同名函数。因为这些函数的语义…

Rust之构建命令行程序(四):用TDD(测试-驱动-开发)模式来开发库的功能

开发环境 Windows 11Rust 1.75.0 VS Code 1.86.2 项目工程 这次创建了新的工程minigrep. 用测试-驱动模式来开发库的功能 既然我们已经将逻辑提取到src/lib.rs中&#xff0c;并将参数收集和错误处理留在src/main.rs中&#xff0c;那么为代码的核心功能编写测试就容易多了。我…

C#浮点运算出错问题

在计算单价等活动的时候&#xff0c;我们经常会用到double 浮点进行运算&#xff0c;但是在乘除的时候经常出现精度丢失问题 decimal 关键字表示 128 位数据类型。 同浮点型相比&#xff0c;decimal 类型具有更高的精度和更小的范围&#xff0c;这使它适合于财务和货币计算 dou…

【MATLAB源码-第146期】基于matlab的信源编码仿真GUI,对比霍夫曼编码,算术编码和LZ编码。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 霍夫曼编码、算术编码和LZ编码是三种广泛应用于数据压缩领域的编码技术。它们各自拥有独特的设计哲学、实现方式和适用场景&#xff0c;因此在压缩效率、编解码速度和内存使用等方面表现出不同的特点。接下来详细描述这三种编…