python初步学习-python文件操作
文件
文件,在
python
中,他是一种类型的对象,类似前面已经学过的其他数据类型,包括文本的、图片的、音频的、视频的等等,还有不少没见过的扩展名的。事实上,在linux
操作系统中,所有的东西都被保存到文件中。
文件属性
>>> dir(file)
['__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__',
'__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', 'close', 'closed', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'mode',
'name', 'newlines', 'next', 'read', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell',
'truncate', 'write', 'writelines', 'xreadlines']
可以看到文件的属性中有__iter__
这个东西,这意味着这种类型的数据是可迭代的iterable
。能够使用for
来读取其中的内容。
读取文件
存在这样一个文件,文件内容如下:
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
使用python
读取文件中的内容需要先创建一个文件的对象。
>>> f = open('file.txt') #创建一个文件对象
>>> type(f)
<type 'file'>
>>> for line in f:
... print line, #后面加一个逗号,就去掉了原来默认增加的\n
...
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
现在在如果在继续print line
,会出现什么情况呢?
>>> for line in f:
... print line,
...
会发现什么输出也没有。这是为什么呢?这个并不是bug
这是因为文件对象中的指针的缘故。这是因为前一次已经读取了文件内容,并且到了文件的末尾了。在重复操作,就是从末尾开始继续读了。当然显示不了什么东西。
创建文件
使用open
上面的试验中,打开的是一个已经存在的文件。那么如何创建文件呢?
>>> wf = open('write_file.txt','w')
>>> type(wf)
<type 'file'>
>>> wf.write('This is a file to test write file function!\n')
查看文件内容
cat write_file.txt
#结果如下
This is a file to test write file function!
可以看到字符串已经被写入到文件中。
写文件与读文件相比,后面增加了一个“w”,这是告诉python
用什么样的模式打开文件。也就是说,用open()
打开文件,可以有不同的模式打开。看下表:
模式 | 描述 |
---|---|
r | 以读方式打开文件,可读取文件信息。 |
w | 以写方式打开文件,可向文件写入信息。如文件存在,则清空该文件,再写入新内容 |
a | 以追加模式打开文件(即一打开文件,文件指针自动移到文件末尾),如果文件不存在则创建 |
r+ | 以读写方式打开文件,可对文件进行读和写操作。 |
w+ | 消除文件内容,然后以读写方式打开文件。 |
a+ | 以读写方式打开文件,并把文件指针移到文件尾。 |
b | 以二进制模式打开文件,而不是以文本模式。该模式只对Windows或Dos有效,类Unix的文件是用二进制模式进行操作的。 |
如果什么模式都不指定,那样默认为r
,以只读的方式打开文件。
值得注意的一点是:
使用open()
函数打开文件,在对文件进行读写操作完成后,要记得使用close()
这个方法关闭文件句柄
例如:
>>> fp = open("open_file.txt","a")
>>> fp.write("\nAha,I like program\n") #向文件中追加
>>> fp.close() #这是关闭文件,一定要养成一个习惯,写完内容之后就关闭
使用with
在对文件进行写入操作之后,一定要牢记一个事情:file.close()
,这个操作千万不要忘记,忘记了怎么办,那就补上吧,也没有什么天塌地陷的后果。
有另外一种方法,能够不用这么让人揪心,实现安全地关闭文件。
>>> with open("with_file.txt","a") as f:
... f.write("\nThis is about 'with...as...'")
...
>>> with open("with_file","r") as f:
... print f.read()
...
hello world!
This is about 'with...as...'
>>>
这里就不用close()了。而且这种方法更有python味道,或者说是更符合Pythonic的一个要求。
文件常用方法
read/readline/readlines
在用dir(file)的时候,会看到三个函数:read/readline/readlines,它们各自有什么特点,为什么要三个?一个不行吗?
read(...)
read([size]) -> read at most size bytes, returned as a string.
If the size argument is negative or omitted, read until EOF is reached.
Notice that when in non-blocking mode, less data than what was requested
may be returned, even if no size parameter was given.
readline(...)
readline([size]) -> next line from the file, as a string.
Retain newline. A non-negative size argument limits the maximum
number of bytes to return (an incomplete line may be returned then).
Return an empty string at EOF.
readlines(...)
readlines([size]) -> list of strings, each a line from the file.
Call readline() repeatedly and return a list of the lines so read.
The optional size argument, if given, is an approximate bound on the
total number of bytes in the lines returned.
使用help()
函数获得三个函数的介绍
对比一下:
- read:如果指定了参数size,就按照该指定长度从文件中读取内容,否则,就读取全文。被读出来的内容,全部塞到一个字符串里面。这样有好处,就是东西都到内存里面了,随时取用,比较快捷;“成也萧何败萧何”,也是因为这点,如果文件内容太多了,内存会吃不消的。
- readline:那个可选参数size的含义同上。它则是以行为单位返回字符串,也就是每次读一行,依次循环,如果不限定size,直到最后一个返回的是空字符串,意味着到文件末尾了(EOF)。
- readlines:size同上。它返回的是以行为单位的列表,即相当于先执行readline(),得到每一行,然后把这一行的字符串作为列表中的元素塞到一个列表中,最后将此列表返回。
读取很大的文件
前面已经说明了,如果文件太大,就不能用read()
或者readlines()
一次性将全部内容读入内存,可以使用while
循环和readline()
来完成这个任务。
此外,还有一个方法:fileinput模块
>>> import fileinput
>>> for line in fileinput.input('file.txt'):
... print line,
...
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
seek
这个函数的功能就是让指针移动。特别注意,它是以字节为单位进行移动的。
f.seek(0)
意图是要回到文件的最开头,那么如果用f.readline()应该读取第一行。
此时指针所在的位置,还可以用tell()来显示,如
f.tell()