利用Python中的输入和输出功能进行读取和写入的教程


Posted in Python onApril 14, 2015

读取、写入和 Python

编写程序的最后一个基本步骤就是从文件读取数据和把数据写入文件。阅读完这篇文章之后,可以在自己的 to-do 列表中加上检验这个技能学习效果的任务。
简单输出

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

>>> 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 文件,并像下面那样显示它的内容。

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

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

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

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

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

>>> 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. 从文件读取数据

>>> 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. 读取和解析行

>>> 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. 读取数据

>>> 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. 写入数据

>>> 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. 处理二进制数据

>>> 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 对象时,使用添加模式。

Python 相关文章推荐
Python3基础之list列表实例解析
Aug 13 Python
实例讲解Python中SocketServer模块处理网络请求的用法
Jun 28 Python
Python3 适合初学者学习的银行账户登录系统实例
Aug 08 Python
微信跳一跳游戏python脚本
Apr 01 Python
Pipenv一键搭建python虚拟环境的方法
May 22 Python
Python格式化输出字符串方法小结【%与format】
Oct 29 Python
python画图系列之个性化显示x轴区段文字的实例
Dec 13 Python
Python使用pymongo库操作MongoDB数据库的方法实例
Feb 22 Python
pycharm new project变成灰色的解决方法
Jun 27 Python
Python Pandas对缺失值的处理方法
Sep 27 Python
Python笔记之观察者模式
Nov 20 Python
matplotlib jupyter notebook 图像可视化 plt show操作
Apr 24 Python
对于Python编程中一些重用与缩减的建议
Apr 14 #Python
归纳整理Python中的控制流语句的知识点
Apr 14 #Python
Python中为什么要用self探讨
Apr 14 #Python
Python中的特殊语法:filter、map、reduce、lambda介绍
Apr 14 #Python
详解Python中for循环的使用
Apr 14 #Python
Python中join和split用法实例
Apr 14 #Python
Python中__name__的使用实例
Apr 14 #Python
You might like
php指定函数参数默认值示例代码
2013/12/04 PHP
php使用post数组的键值创建同名变量并赋值的方法
2015/04/03 PHP
Symfony2创建基于域名的路由相关示例
2016/11/14 PHP
Yii2框架控制器、路由、Url生成操作示例
2019/05/27 PHP
再次更新!MSClass (Class Of Marquee Scroll通用不间断滚动JS封装类 Ver 1.6)
2007/02/05 Javascript
JS无限极树形菜单,json格式、数组格式通用示例
2013/07/30 Javascript
JS关键字球状旋转效果的实例代码
2013/11/29 Javascript
jQuery判断元素是否存在的可靠方法
2014/05/06 Javascript
JavaScript中的对象的extensible属性介绍
2014/12/30 Javascript
jQuery实现友好的轮播图片特效
2015/01/12 Javascript
jQuery手动点击实现图片轮播特效
2020/04/20 Javascript
js原生代码实现轮播图的实例讲解
2017/07/28 Javascript
Canvas放置反弹效果随机图形(实例)
2017/08/17 Javascript
玩转Koa之koa-router原理解析
2018/12/29 Javascript
vue实现鼠标移入移出事件代码实例
2019/03/27 Javascript
layui 富文本图片上传接口与普通按钮 文件上传接口的例子
2019/09/23 Javascript
浅谈layui里的上传控件问题
2019/09/26 Javascript
JavaScript函数IIFE使用详解
2019/10/21 Javascript
webpack proxy 使用(代理的使用)
2020/01/10 Javascript
[00:43]TI7不朽珍藏III——幽鬼不朽展示
2017/07/15 DOTA
[51:32]Optic vs Serenity 2018国际邀请赛淘汰赛BO3 第一场 8.22
2018/08/23 DOTA
python pandas 对series和dataframe的重置索引reindex方法
2018/06/07 Python
使用 Supervisor 监控 Python3 进程方式
2019/12/05 Python
python paramiko远程服务器终端操作过程解析
2019/12/14 Python
详解PyQt5中textBrowser显示print语句输出的简单方法
2020/08/07 Python
python中温度单位转换的实例方法
2020/12/27 Python
英国第一摩托车和摩托车越野配件商店:GhostBikes
2019/03/10 全球购物
初中生个人学习的自我评价
2013/12/04 职场文书
酒店办公室文员岗位职责
2013/12/18 职场文书
关于人生的感言
2014/01/17 职场文书
大学考试作弊检讨书
2014/01/30 职场文书
就业自我评价
2014/02/04 职场文书
MySQL 常见的数据表设计误区汇总
2021/06/07 MySQL
Python爬取某拍短视频
2021/06/11 Python
OpenCV绘制圆端矩形的示例代码
2021/08/30 Python
win10如何更改appdata文件夹的默认位置?
2022/07/15 数码科技