读取文件

假设你已经在某个文件夹下创建了 “test.txt” 文件,且里面有一些内容,那你在当前位置输入 Python3,进入到交互模式,然后执行下面的操作:

>>> f = open('test.txt')
>>> for line in f:
... print(line)
...
My name is Rocky I love Python

这里提醒大家注意一下,如果是在该文件所在的位置启动的 Python 交互模式,那么按照上面的方法 open(‘test.txt’) 打开文件,这意味着 test.txt 是在当前文件夹下的,如果要打开其它文件夹下的文件,要使用相对路径或者绝对路径来表示,从而让 Python 能找到那个文件。

看上面的例子,open() 一个文件,即生成了一个对象,把这个对象赋值给变量 f,从而让变量 f 和文件对象之间建立了引用关系,接下来用 for 循环读取文件中的内容,把读到的文件中的每行赋值给变量 line (这里的每行可以看作是对象),从打印的结果看,每一行与你读取的文件的每一行是相同的。

如果你做完了上述操作,那么请看下面的操作:

>>> for line1 in f:
... print(line1)
...
>>>

你会奇怪的发现,竟然什么也没有,是不是出错了?其实并没有,因为之前已经读取过一次文件的内容了,并且到了文件的末尾,再重复操作,就要从文章的末尾开始读了,当然就没有什么东西了,在 Python 中并不会认为这是错误。如果你想再次读取的话,请重新 open() 一下文件。

创建文件

读文件只是针对文件的操作之一,还有创建文件。

在上面读文件的时候,我们打开的是一个已经存在的文件,那么如何创建一个新文件呢?请看下面的操作:

>>> new_file = open('new.txt','w')
>>> new_file.write('this is a new file')
18
>>> new_file.close()

new_file = open(‘new.txt’,’w’) 意味着在当前的目录下创建了一个名为 new_file 的文件,该文件为 “w” 打开模式。

new_file.write('this is a new file’) 则是向已建立的新文件中写入 “this is a new file”,并且返回的是写入字符串的长度。

new_file.close() 则是关闭当前文件,然后将写入的话保存到文件中。

由上面的例子我们可以看出,创建文件我们同样用的是 open() ,但是多了个 “w” ,这是告诉 Python 用什么模式打开文件。在 Python 中,可以用很多不同的模式打开文件,请看下图(截图来自菜鸟教程):



从上图中可以看出,不同的模式下打开文件可以进行不同的读写操作,如果什么都不写的话,默认为以只读(r)的方式打开文件。

使用 with 自动关闭文件

在前面的操作中我们可以看到,在对文件进行写操作之后,要执行关闭文件的操作,执行关闭文件的操作是为了将写入的内容保存到文件中,如果不进行 close() 操作的话,那么新写入的内容将不会被保存。

Python 早就知道会有很多马大哈们会忘记 close()的操作,所以它创建了一种简单的方法,这就是 with,它会实现自动关闭文件,看!Python 是多么的人性化!请看下面的操作:

>>> new_file.close()
>>> with open('new.txt','a') as f:
... f.write(‘\nwith is good good good.')
...
23

在这里 with 其实是要发起一个语句的,这里兼具了后面我会讲的 try/finally,即可以在遇到异常的时候发出提醒,此处暂时先不讲,等以后我再细说,我们先学会用 with。

>>> with open('new.txt') as f:
... print(f.read())
...
this is a new file
with is good good good.

看吧,在 with 中我们可以放轻松的扔掉 close 了,上面例子中用到的 read() 方法,在明天的文章中我会讲到。

文件的属性

很多时候,我们需要获取一个文件的有关属性,比如文件的创建日期,修改日期等等,在 Python 中有一个专门针对时间设计的模块 -- time。请看下面的操作:

>>> import time
>>> time.localtime()
time.struct_time(tm_year=2018, tm_mon=7, tm_mday=25, tm_hour=21, tm_min=49, tm_sec=32, tm_wday=2, tm_yday=206, tm_isdst=0)

其实还有一种办法可以查看文件的这些属性,就是 os 模块里的 stat,在这里我就是提一嘴,之后讲到 os 模块的时候再仔细说。

读取文件的内容

因为文件的对象是可迭代的,所以能够用open() 打开文件,所以用 for 循环可以将文件的内容读出来。我在前面的文章说过,可以用 dir() 查看文件对象的属性和方法,当你看了以后你会发现有 3 个方法 read / readline / readlines,单单从名称上看,它们应该和读有关系,事实上确实是这样的,但是它们 3 个又有些微的差别。

1.read()

文件对象的 read() 方法,其实完整的写出来其实是 read( size ),只不过里面的参数可以省略,如果不省略,则读取文件中的 size 个字符并返回一个字符串;如果省略的话,则读取文件对象的字符知道 EOF,EOF == End - of - file。

>>> f = open('new.txt')
>>> f.read(10)
'this is a '
>>> f.read()
'new filewith is good good good.’

如果你是按照上述的例子依次进行操作的,就会在 f.read() 后出现上述的结果,这主要是因为在前面已经 read(12) 了,指针已经移动到了第 12 个字符后面。

2.readline() & readlines()

readline() 就是它表面的意思,逐行读取文件的内容。

>>> f = open('new.txt')
>>> f.readline()
'this is a new filewith is good good good.'
>>> f.readline()
''

每次执行 readline() 的时候它只读一行,直到最后一行,如果还执行 readline() 的话,它不会报错,返回的是空字符串。

同样也是有 readline(size) 的,如果给 readline(size) 参数,则读取相应行的 size 个字符,有兴趣的可以自己试一下。

还有一个是 readlines(),它的作用是将文件中各行读出来,放到一个列表中返回。

>>> f = open('test.txt')
>>> f.readlines()
['My name is Rocky\n', 'I love Python’]

既然返回的是一个列表,那么就能用 for 循环读取列表元素,再观察一下可以发现,列表中的每个元素都是文件的一行,并且是字符串。

>>> f = open('test.txt')
>>> for line in f.readlines():
... print(line)
...
My name is Rocky I love Python

这个是不是让你觉得和上面文件的 for 循环很类似?

>>> f = open('test.txt')
>>> for line in f:
... print(line)
...
My name is Rocky I love Python

乍一看两种方式好像没有什么区别,其实这两种方式是不同的。在 for line in f 中,并没有将文件中所以的行都读入内存,而 for line in f.readlines() 中先执行了 f.readlines(),在内存中有一个列表,列表中包含了所有文件的行,这就是两种方式的区别。

大文件的读取

上面的三个读取文件内容的方法 read 和 readlines 都是一次性将全部的内容读入内存,如果文件不是很大的话,这种做法能够保证读取的速度,但是如果文件内容很大,大到差不多内存那么大或者更大的时候,就不能这么做了。但是 Python 早就替你考虑到了,Python 中有一个 fileinput 模块,可以使用它来操作。

>>> import fileinput
>>> for line in fileinput.input('test.txt'):
... print(line,end = '')
...
My name is Rocky
I love Python

因为我没有大的文件,只是为了演示一下这个模块的用法,对于这个模块更多的内容,可以在交互模式下用 dir() 去查看。

seek

不知道你有没有奇怪过在之前的演示中,每次都要做 f = open(‘***’) 类似的操作,否则就会出现下面的情况:

>>> f = open('test.txt')
>>> for line in f:
... print(line)
...
My name is Rocky I love Python
>>> for line in f:
... print(line)
...
>>>

是不是发现,当我们第二次循环文件的时候,既没有报错,也没有显示文件的内容,类似的现象在前面的 readline 中也出现过,这是因为读取文件的时候,有指针随着运动,当读取结束时,指针就到了相应的位置。

当指针结束运动时,可以使用 tell() 告诉我们当前指针的位置。

>>> f = open('test.txt')
>>> f.readline()
'My name is Rocky\n'
>>> f.tell()
17

现在我们来看 seek() 的能力,它能够根据偏移量来移动指针。

>>> f.seek(0)
0

上面的意思是将指针移动到文件的开始,如果用 f.readline() 读取的话,现在输出的应该是文件的第一行:

>>> f.readline()
'My name is Rocky\n’

其实还可以操纵指针到任何一个位置,请看下面的操作:

>>> f.seek(10)
10
>>> f.tell()
10

f.seek(10) 就是将位置定位到从开头算起到第 10 个字符后面,这时候如果使用 readline 的话,读取的是从当前位置到行末的字母。

写在之后

更多内容,欢迎关注公众号「Python空间」,期待和你的交流。

我爱学 Python 之文件的更多相关文章

  1. python之文件的读写(2)

    小R昨天因为在研究weblogic的漏洞就没来得及学习python(好吧,这都是借口,懒了,大家可不能像我这样.要坚持每天都学).   这个进度是有点慢呀.哎呀,没事没事,我还年轻,才20岁.  哈哈 ...

  2. 简学Python第二章__巧学数据结构文件操作

    #cnblogs_post_body h2 { background: linear-gradient(to bottom, #18c0ff 0%,#0c7eff 100%); color: #fff ...

  3. 小白学 Python(18):基础文件操作

    人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...

  4. 【C++程序员学 python】python 的文件类型

    python的文件类型主要分为3种,分别是源代码.字节代码和优化代码.这些代码都可以直接运行,不需要进行编译或者连接.这正是python语言的特性,python的文件通过python.exe 或pyt ...

  5. 【Python五篇慢慢弹】快速上手学python

    快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...

  6. 数百种编程语言,而我为什么要学 Python?

    是应用率最高.长期霸占排行榜的常青藤 Java?是易于上手,难以精通的 C?还是在游戏和工具领域仍占主流地位的 C++?亦或是占据 Windows 桌面应用程序半壁江山的 C#?…… 我想,每个人可能 ...

  7. <-0基础学python.第一课->

    初衷:我电脑里面的歌曲很久没换了,我想听一下新的歌曲,把他们下载下来听,比如某个榜单的,但是一首一首的点击下载另存为真的很恶心 所以我想有没有办法通过程序的方式来实现,结果还真的有,而且网上已经有有人 ...

  8. Python之文件读写

    本节内容: I/O操作概述 文件读写实现原理与操作步骤 文件打开模式 Python文件操作步骤示例 Python文件读取相关方法 文件读写与字符编码 一.I/O操作概述 I/O在计算机中是指Input ...

  9. 简学Python第一章__进入PY的世界

    #cnblogs_post_body h2 { background: linear-gradient(to bottom, #18c0ff 0%,#0c7eff 100%); color: #fff ...

随机推荐

  1. HDU1043 八数码(BFS + 打表)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 , 康托展开 + BFS + 打表. 经典八数码问题,传说此题不做人生不完整,关于八数码的八境界 ...

  2. linux 命令——35 ln(转)

    ln 是linux中又一个非常重要命令,它的功能是为某一个文件在另外一个位置建立一个同步的链接.当我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要 ...

  3. IOS UIActivityIndicatorView动画

    ● 是一个旋转进度轮,可以用来告知用户有一个操作正在进行中,一般 用initWithActivityIndicatorStyle初始化 ● 方法解析: ● - (void)startAnimating ...

  4. Aizu 0033 Ball(dfs,贪心)

    日文题面...题意:是把一连串的有编号的球往左或者往右边放.问能不能两边都升序. 记录左边和右边最上面的球编号大小,没有就-1,dfs往能放的上面放. #include<bits/stdc++. ...

  5. NOIP2018初赛 解题报告

    前言 \(NOIP2018\)初赛已经结束了,接下来就要准备复赛了. 不过,在此之前,还是先为初赛写一篇解题报告吧. 单项选择题 送分题.(虽然我还是做错了)可以考虑将它们全部转化为\(10\)进制, ...

  6. Json的本地写入和读取,也可以方便在开发中数据的调试

    不知道小伙伴们,在开发中,数据调试的过程中,尤其是很多状态的情况下调试,是不是总是麻烦后台的小哥改变不同的状态,总感觉这样太麻烦了, 那么就可以,把数据写入到本地,然后去沙盒中,找到这个写入的文件,直 ...

  7. 2754: C++习题-快速排序

    2754: C++习题-快速排序 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 921  Solved: 406[Submit][Status][Web ...

  8. HTML第四章:初始css

    CSS样式:                 一.为什么要使用CSS;可以让页面更美观.有利于开发速度.                 二.什么是CSS:全称cascading style shee ...

  9. P4744 A’s problem(a)

    时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试题,每三天结算一次成绩.参与享优惠 描述 这是一道有背景的题目,小A也是一个有故事的人.但可惜的 ...

  10. Redis常用诊断命令

    1.info 命令查看redis信息,可以指定要查看的section名 sections:Server,clients,memory,persistence,stats,replication,cpu ...