用 Python 的输入输出功能读取和写入数据_将字符串写入文本文件,然后再读取并输出。字符串内容为“hello world\n文本文件的-程序员宅基地

技术标签: Python  

读取、写入和 Python

在 “探索 Python” 系列以前的文章中,学习了基本的 Python 数据类型和一些容器数据类型,例如 tuplestring 和 list。其他文章讨论了 Python 语言的条件和循环特性,以及它们如何与容器数据类型进行协作来简化编程任务。编写程序的最后一个基本步骤就是从文件读取数据和把数据写入文件。阅读完这篇文章之后,可以在自己的 to-do 列表中加上检验这个技能学习效果的任务。

简单输出

贯穿整个系列,一直用 print 语句写入(输出)数据,它默认把表达式作为 string 写到屏幕上(或控制台窗口上)。清单 1 演示了这一点。清单 1 重复了第一个 Python 程序 “Hello, World!”,但是做了一些小的调整。

清单 1. 简单输出
1
2
3
4
5
6
7
8
9
10
>>> print "Hello World!"
Hello World!
>>> print "The total value is = $", 40.0*45.50
The total value is = $ 1820.0
>>> print "The total value = $%6.2f" % (40.0*45.50)
The total value = $1820.00
>>> myfile = file("testit.txt", 'w')
>>> print >> myfile, "Hello World!"
>>> print >> myfile, "The total value = $%6.2f" % (40.0*45.50)
>>> myfile.close()

正如这个示例演示的,用 print 语句写入数据很容易。首先,示例输出一个简单的 string。然后创建并输出复合的 string,这个字符串是用 string 格式化技术创建的。

但是,在这之后,事情发生了变化,与代码以前的版本不同。接下来的一行创建 file 对象,传递进名称 "testit.txt" 和 'w'字符(写入文件)。然后使用修改过的 print 语句 —— 两个大于号后边跟着容纳 file 对象的变量 —— 写入相同的 string。但是这一次,数据不是在屏幕上显示。很自然的问题是:数据去哪儿了?而且,这个 file 对象是什么?

第一个问题很容易回答。请查找 testit.txt 文件,并像下面那样显示它的内容。

1
2
3
% more testit.txt
Hello World!
The total value = $1820.00

可以看到,数据被准确地写入文件,就像以前写到屏幕上一样。

现在,请注意清单 1 中的最后一行,它调用 file 对象的 close 方法。在 Python 程序中这很重要,因为在默认情况下,文件输入和输出是缓冲的;在调用 print 语句时,数据实际未被写入;相反,数据是成批写入的。让 Python 把数据写入文件的最简单方式就是显式地调用 close 方法。

文件对象

file 是与计算机上的文件进行交互的基本机制。可以用 file 对象读取数据、写入数据或把数据添加到文件,以及处理二进制或文本数据。

学习 file 对象的最简单方法就是阅读帮助,如清单 2 所示。

清单 2. 得到 file 对象的帮助
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
>>> help(file)
Help on class file in module __builtin__:
class file(object)
  |  file(name[, mode[, buffering]]) -> file object
 
  |  Open a file.  The mode can be 'r', 'w' or 'a' for reading (default),
  |  writing or appending.  The file will be created if it doesn't exist
  |  when opened for writing or appending; it will be truncated when
  |  opened for writing.  Add a 'b' to the mode for binary files.
  |  Add a '+' to the mode to allow simultaneous reading and writing.
  |  If the buffering argument is given, 0 means unbuffered, 1 means line
  |  buffered, and larger numbers specify the buffer size.
  |  Add a 'U' to mode to open the file for input with universal newline
  |  support.  Any line ending in the input file will be seen as a '\n'
  |  in Python.  Also, a file so opened gains the attribute 'newlines';
  |  the value for this attribute is one of None (no newline read yet),
  |  '\r', '\n', '\r\n' or a tuple containing all the newline types seen.
 
  |  'U' cannot be combined with 'w' or '+' mode.
 
  |  Note:  open() is an alias for file().
 
  |  Methods defined here:
...

正如帮助工具指出的,使用 file 对象很简单。用 file 构造函数或 open 方法创建 file 对象,open 是 file 构造函数的别名。第二个参数是可选的,它指定文件的使用方式:

  • 'r' (默认值)表示从文件读取数据。
  • 'w' 表示要向文件写入数据,并截断以前的内容。
  • 'a' 表示要向文件写入数据,但是添加到当前内容尾部。
  • 'r+' 表示对文件进行读写操作(删除以前的所有数据)。
  • 'r+a' 表示对文件进行读写操作(添加到当前内容尾部)。
  • 'b' 表示要读写二进制数据。

这篇文章的第一个代码清单向文件写入数据。现在,清单 3 显示如何把这个数据读入 Python 程序,并解析文件的内容。

清单 3. 从文件读取数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>> myfile = open("testit.txt")
>>> myfile.read()
'Hello World!\nThe total value = $1820.00\n'
>>> str = myfile.read()
>>> print str
>>> myfile.seek(0)
>>> str = myfile.read()
>>> print str
Hello World!
The total value = $1820.00
>>> str.split()
['Hello', 'World!', 'The', 'total', 'value', '=', '$1820.00']
>>> str.split('\n')
['Hello World!', 'The total value = $1820.00', '']
>>> for line in str.split('\n'):
...     print line
...
Hello World!
The total value = $1820.00
>>> myfile.close()

要读取数据,首先要创建合适的 file 对象 —— 在这个示例中,文件对象打开 testit.txt 文件,并用 read 方法读取内容。这个方法把整个文件读入一个 string,然后在程序中把这个字符串输出到控制台。在对 read 方法的第二个调用中,试图把值分配给 str 变量,结果返回一个空的 string。这是因为第一个 read 操作读入了整个文件。当试图再次读取内容时,已经到了文件末尾,所以什么也读不到。

这个问题的解决方案也很简单:让 file 对象返回文件的开头。回到开头要通过 seek 方法进行,它接受一个参数,表示要从文件中的什么位置开始读取或写入(例如,0 代表文件开头)。seek 方法支持更复杂的操作,但是可能会有危险。对于目前来说,我们还坚持采用简单方式。

现在回到了文件的开始之处,可以把文件内容读入 string 变量并对 string 做适当地解析。请注意,在文件中,行之间用新行(或行结束)字符区分。如果试着在 string 上调用 split 方法,它会在空白字符(例如空格)处进行拆分。为了让方法根据新行字符拆分各行,必须显式地指定新行字符。然后可以拆分 string 并在 for 循环中对文件的行进行迭代。

看起来仅仅从文件中读取和处理一行内容都有许多工作要做。Python 要让简单的事情变容易,所以您可能想知道这个任务有没有快捷方式可用。如清单 4 所示,答案是 yes。

清单 4. 读取和解析行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> myfile = open("testit.txt")
>>> for line in myfile.readlines():
...     print line
...
Hello World!
The total value = $1820.00
>>> myfile.close()
>>> for line in open("testit.txt").readlines():
...     print line
...
Hello World!
The total value = $1820.00
>>> for line in open("testit.txt"):
...     print line
...
Hello World!
The total value = $1820.00

清单 4 演示了读取和解析文本文件行的三种技术。首先,打开文件并把它分配给变量。然后调用 readlines 方法,把整个文件读入内存并把内容拆分成 string 列表。for 循环在 string 列表上进行迭代,一次输出一行。

第二个 for 循环通过使用 file 对象的隐式变量(也就是说,变量不是显式创建的),对这个过程稍做了点儿简化。打开文件和读取文件内容一次完成,生成的效果与第一个显式示例相同。最后一个示例进一步做了简化,并演示了直接在 file 对象上进行迭代的能力(请注意,这是 Python 的一个新特性,所以在您的计算机上可能无法工作)。在这个示例中,创建隐式 file对象,然后 Python 做余下的工作,允许对文件中的全部行进行迭代。

但是,有些时候,在从文件读取数据时,可能想要更好的控制级别。在这种情况下,应当使用 readline 方法,如清单 5 所示。

清单 5. 读取数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
>>> myfile = open("testit.txt")
>>> myfile.readline()
'Hello World!\n'
>>> myfile.readline()
'The total value = $1820.00\n'
>>> myfile.readline()
''
>>> myfile.seek(0)
>>> myfile.readline()
'Hello World!\n'
>>> myfile.tell()
13L
>>> myfile.readline()
'The total value = $1820.00\n'
>>> myfile.tell()
40L
>>> myfile.readline()
''
>>> myfile.tell()
40L
>>> myfile.seek(0)
>>> myfile.read(17)
'Hello World!\nThe '
>>> myfile.seek(0)
>>> myfile.readlines(23)
['Hello World!\n', 'The total value = $1820.00\n']
>>> myfile.close()

这个示例演示了如何在文件中移动,一次读取一行,或者显式地用 seek 方法移动文件位置指示器。首先,用 readline 方法在文件行中移动。当到达文件末尾时,readline 方法返回一个空的 string。在过了文件末尾之后,如果还用这种方式继续读取,并不会造成错误,只会返回空的 string

然后返回文件开始的地方,并读取另一行。 tell 方法显示出在文件中的当前位置(应当在第一行文本之后) —— 在这个示例中,在第 13 个字符位置。通过使用这个知识,可以向 read 或readline 方法传递一个参数,控制读取的字符数。对于 read方法,这个参数(在这个示例中是 17)是要从文件中读取的字符数。但是 readline 方法在读入指定数量的字符后,还会继续读取,直到行尾。在这个示例中,它读取第一行和第二行文本。

写入数据

迄今为止的示例都侧重于读取数据,而不是写入数据。但是如清单 6 所示,一旦了解了使用 file 对象的基础知识,写入也很容易。

清单 6. 写入数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
>>> mydata = ['Hello World!', 'The total value = $1820.00']
>>> myfile = open('testit.txt', 'w')
>>> for line in mydata:
...     myfile.write(line + '\n')
...
>>> myfile.close()
>>> myfile = open("testit.txt")
>>> myfile.read()
'Hello World!\nThe total value = $1820.00\n'
>>> myfile.close()
>>> myfile = open("testit.txt", "r+")
>>> for line in mydata:
...     myfile.write(line + '\n')
...
>>> myfile.seek(0)
>>> myfile.read()
'Hello World!\nThe total value = $1820.00\n'
>>> myfile.close()
>>> myfile = open("testit.txt", "r+a")
>>> myfile.read()
'Hello World!\nThe total value = $1820.00\n'
>>> for line in mydata:
...     myfile.write(line + '\n')
...
>>> myfile.seek(0)
>>> myfile.read()
'Hello World!\nThe total value = $1820.00\nHello World!\nThe total value = $1820.00\n'
>>> myfile.close()

要把数据写入文件,必须先创建 file 对象。但是,在这情况下,必须用 'w' 模式标记指定要写入文件。在这个示例中,把 mydata list 的内容写入文件,关闭文件,然后重新打开文件,这样就可以读取内容了。

但是,通常情况下,想要同时读取文件和写入文件,所以这个示例的下一部分用 'r+' 模式重新打开文件。因为能够写入文件,而不是添加,所以文件会被截断。首先,把 mydata list 的内容写入文件,然后把文件指针重新定位到文件开头,并读入内容。然后这个示例关闭文件,并用读取和添加模式 "r+a" 重新打开文件。正如示例代码所示,文件内容现在是两个写入操作的结果(文本是重复的)。

处理二进制数据

前面所有的示例都处理文本数据或字符数据:写入和读取字符 string。但是,在某些情况下,例如在处理整数或压缩文件时,需要能够读取和写入二进制数据。在创建 file 对象时,通过把 'b' 添加到文件模式中,可以很容易地用 Python 处理二进制数据,如清单 7 所示。

清单 7. 处理二进制数据
1
2
3
4
5
6
7
8
9
>>> myfile = open("testit.txt", "wb")
>>> for c in range(50, 70):
...     myfile.write(chr(c))
...
>>> myfile.close()
>>> myfile = open("testit.txt")
>>> myfile.read()
'23456789:;<=>?@ABCDE'
>>> myfile.close()

在这个示例中,创建一个合适的 file 对象,然后用从 50 到 69 的 ASCII 值写入二进制字符。使用 chr 方法,把 range 方法调用创建的整数转变成字符。在写完所有数据之后,关闭文件并重新打开文件进行读取,还是使用二进制模式标记。读取文件可以证明没有把整数写入文件,相反,写的是字符值。

在读取和写入二进制数据时,必须小心,因为不同的平台用不同的方式保存二进制数据。如果必须处理二进制数据,最好是使用来自 Python 库的合适对象(或者来自第三方开发人员的对象)。

读取和写入:最有趣的地方

这篇文章讨论了在 Python 程序中如何从文件读取数据和写入数据到文件中。总体来说,过程很简单:创建合适的 file 对象,然后按照需要读取和写入。但是,在使用写入模式创建 file 文件,向文件写入数据时,必须注意文件的截断。如果需要向文件中添加数据,应当在创建 file 对象时,使用添加模式。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yaoxy/article/details/79428420

智能推荐

在Google使用Borg进行大规模集群的管理 7-8-程序员宅基地

文章浏览阅读606次。为什么80%的码农都做不了架构师?>>> ..._google trace batch job

python加密字符串小写字母循环后错两位_python学习:实现将字符串进行加密-程序员宅基地

文章浏览阅读2.6k次,点赞3次,收藏3次。'''题目描述1、对输入的字符串进行加解密,并输出。2加密方法为:当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如字母a时则替换为B;字母Z时则替换为a;当内容是数字时则把该数字加1,如0替换1,1替换2,9替换0;其他字符不做变化。s'''#-*-coding:utf-8-*-importre#判断是否是字母defisLetter(letter):iflen..._编写函数fun2实现字符串加密,加密规则为:如果是字母,将其进行大小写转换;如果

【Java容器源码】集合应用总结:迭代器&批量操作&线程安全问题_迭代器是否可以保证容器删除和修改安全操作-程序员宅基地

文章浏览阅读4.4k次,点赞6次,收藏8次。下面列出了所有集合的类图:每个接口做的事情非常明确,比如 Serializable,只负责序列化,Cloneable 只负责拷贝,Map 只负责定义 Map 的接口,整个图看起来虽然接口众多,但职责都很清晰;复杂功能通过接口的继承来实现,比如 ArrayList 通过实现了 Serializable、Cloneable、RandomAccess、AbstractList、List 等接口,从而拥有了序列化、拷贝、对数组各种操作定义等各种功能;上述类图只能看见继承的关系,组合的关系还看不出来,比如说_迭代器是否可以保证容器删除和修改安全操作

养老金融:编织中国老龄社会的金色安全网

在科技金融、绿色金融、普惠金融、养老金融、数字金融这“五篇大文章”中,养老金融以其独特的社会价值和深远影响,占据着不可或缺的地位。通过政策引导与市场机制的双重驱动,激发金融机构创新养老服务产品,如推出更多针对不同年龄层、风险偏好的个性化养老金融产品,不仅能提高金融服务的可获得性,还能增强民众对养老规划的主动参与度,从而逐步建立起适应中国国情、满足人民期待的养老金融服务体系。在人口老龄化的全球趋势下,中国养老金融的发展不仅仅是经济议题,更关乎社会的稳定与进步。养老金融:民生之需,国计之重。

iOS 创建开源库时如何使用图片和xib资源

在需要使用图片的地方使用下面的代码,注意xib可以直接设置图片。将相应的图片资源文件放到bundle文件中。

R语言学习笔记9_多元统计分析介绍_r语言多元统计分析-程序员宅基地

文章浏览阅读3.6k次,点赞4次,收藏66次。目录九、多元统计分析介绍九、多元统计分析介绍_r语言多元统计分析

随便推点

基于psk和dpsk的matlab仿真,MATLAB课程设计-基于PSK和DPSK的matlab仿真-程序员宅基地

文章浏览阅读623次。MATLAB课程设计-基于PSK和DPSK的matlab仿真 (41页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!9.90 积分武汉理工大学MATLAB课程设计.目录摘要 1Abstract 21.设计目的与要求 32.方案的选择 42.1调制部分 42.2解调部分 43.单元电路原理和设计 63.1PCM编码原理及设计 63.1.1PCM编码原理 ..._通信原理课程设计(基于matlab的psk,dpsk仿真)(五篇模版)

腾讯微搭小程序获取微信用户信息_微搭 用微信号登录-程序员宅基地

文章浏览阅读3.5k次,点赞6次,收藏28次。腾讯微搭小程序获取微信用户信息无论你对低代码开发的爱与恨, 微信生态的强大毋庸置疑. 因此熟悉微搭技术还是很有必要的! 在大多数应用中, 都需要获取和跟踪用户信息. 本文就微搭中如何获取和存储用户信息进行详细演示, 因为用户信息的获取和存储是应用的基础.一. 微搭每个微搭平台都宣称使用微搭平台可以简单拖拽即可生成一个应用, 这种说法我认为是"夸大其词". 其实微搭优点大致来说, 前端定义了很多组件, 为开发人员封装组件节省了大量的时间,这是其一; 其二对后端开发来说, 省去了服务器的部署(并没有省去后_微搭 用微信号登录

sql中索引的使用分析

sql中索引的使用分析

termux安装metasploit()-程序员宅基地

文章浏览阅读8.9k次,点赞16次,收藏108次。因为呢,termux作者,不希望让termux变成脚本小子的黑客工具,于是把msf , sqlmap等包删了。至于如何安装metasploit呢。apt update -y && apt upgrade -y #更新升级更新升级之后要安装一个叫 git 的安装包apt install git -y然后我们就开始//这里的话建议把手机放到路由器旁边,保持网络的优良。或者科学上网。//git clone https://github.com/gushmazuko/metaspl_termux安装metasploit

armbian docker Chrome_一起学docker06-docker网络-程序员宅基地

文章浏览阅读141次。一、Docker支持4种网络模式Bridge(默认)--network默认网络,Docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中;IP地址段是172.17.0.1/16 独立名称空间 docker0桥,虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。host容器不会获得一个独立的network namespace,而是与宿主..._armbian 172.17.0.1

Ansible-Tower安装破解

Ansible-Tower安装破解。

推荐文章

热门文章

相关标签