文件
打开/创建文件(open):open()一个文件,也就生成了一个文件对象,将这个对象赋值给变量f,这样变量f就和文件对象建立了引用关系。open()函数的可选参数很多,其中参数buffer是用于指定缓存的操作。
>>> f = open('test.txt') # 打开文件 >>> for line in f: # 遍历输出文件中的每行内容 ... print(line) ... How to learn python? # 在原文中,每行结束都有本行的结束符号\n,表示换行 # 使用print(line)对打印出文件中的换行,自己也会输出换行 please login python.org then you can start your learning
关闭文件(close): close方法有两个功能,关闭文件和保存文件。
若不想关闭文件而又要保存时,可用flush,flush会刷入文件到硬盘中保存。
write将文件的内容暂时写入内存中,执行flush才会将文件内容写入硬盘中保存,但是flush有时候不一定管用,所以保险的保存文件的方式还是执行文件关闭。
除此之外,写入内容之后,执行一次文件读取read,也会将内容自动保存到硬盘中。
文件操作执行完毕后,必须调用close()方法关闭文件。close方法的作用有两个:关闭文件;保存文件。若向文件中写入了新内容而没有调用close方法,则写入的内容将不会被保存到文件中。
文件的状态:
在os模块中,有查看文件状态的方法stat()。可查看文件的状态,比如创建日期、修改日期、文件大小等。
>>> import os >>> os.stat('test.txt') os.stat_result(st_mode=33188, st_ino=17549, st_dev=2049, st_nlink=1, st_uid=0, st_gid=0, st_size=78, st_atime=1536029781, st_mtime=1536029723, st_ctime=1536029723)
读文件:
read()方法:完整的写出来应该是read(size),它有一个可选参数size。当size省略时,从光标当前位置读取文件内容至结尾;当传入size参数时,从光标当前位置读取size个字符。最终都是返回一个字符串,字符串中包含文件的换行符。
>>> f = open('test.txt') # 先打开文件 >>> f.read() # 读取文件所有内容,返回一个字符串,包含文件的换行符 'How to learn python?\nplease login python.org\nthen you can start your learning\n' >>> f = open('test.txt') >>> f.read(-3) # 传入size参数为负数,也表示从光标当前位置读取全部内容 'How to learn python?\nplease login python.org\nthen you can start your learning\n' >>> f = open('test.txt') # 重新打开文件 >>> f.read(6) # 读取前六个字符 'How to' >>> f.read(7) # 光标从第七个字符开始继续读取后面的七个字符 ' learn '
readline()方法:逐行读取文件内容,每次执行一次只读取一行,直到最后一行。如果还继续执行,则返回空字符串,不会报错。
>>> f = open('test.txt') >>> f.readline() # 每次执行一次只读取一行 'How to learn python?\n' >>> f.readline() # 每次执行一次只读取一行 'please login python.org\n' >>> f.readline() # 直到读取完最后一行 'then you can start your learning\n' >>> f.readline() # 继续执行,返回空字符串,不报错 ''
此外readline()方法还可传入size参数,表示读取相应行的size个字符。当size小于相应行的字符数,若继续执行readline(size)则会接着读取当前行的内容,直至读取完当前行的内容才换下一行。当size大于相应行的字符数,则只会读取这一行。读取的每行内容都保存为一个字符串,即readline方法返回的是一个字符串。
>>> f = open('test.txt') >>> f.readline(5) # 读取第一行前五个字符 'How t' >>> f.readline(5) # 继续执行,则读取第一行下五个字符 'o lea' >>> f.readline(5) # 继续执行,则读取第一行下五个字符 'rn py' >>> f.readline(5) # 继续执行,则读取第一行下五个字符 'thon?' >>> f.readline(90) # 继续执行,读完第一行内容,包含换行符 '\n' >>> f.readline(90) # size大于当前行的字符数时,不会换行继续读,只会读完当前行结束 'please login python.org\n'
readlines()方法:将文件中每行内容都读出来,包含每行的换行符,放到一个列表中返回。文件中有多少行,列表中就有多少个元素。
>>> f = open('test.txt') # 每行内容都读出来,包含每行的换行符,放到一个列表中,每行内容为列表中的一个元素,且每个元素都是字符串 >>> f.readlines() ['How to learn python?\n', 'please login python.org\n', 'then you can start your learning\n']
可给readlines()方法传入size参数,传入参数后若参数小于一行的字符数,则返回一行。若参数大于一行的字符数,则返回多行。
读很大的文件:当文件很大,乃至于内存空间不足,就不能使用以上读取文件的方法了。python中有一个fileinput模块,可以用来读取很大的文件。
>>> import fileinput >>> for line in fileinput.input('fabfile.py'): ... print(line, end='') ... from fabric.api import * import datetime env.user = 'ubuntu1' env.hosts = '192.168.137.132' ……省略后面的内容
seek:当读取文件的时候,有指针随着运动,当读取结束时,指针就移动到相应的位置。要获取当前指针所在的位置,可以用tell()方法;要重置指针的位置,可以用seek()方法,它能根据偏移量移动指针。
>>> f = open('test.txt') >>> f.read(5) # 读取前五个字符,此时指针位于第五个字符后面 'How t' >>> t.tell() # 获取指针的位置 5 >>> f.read(15) 'o learn python?' >>> f.tell() # 获取指针的位置 20 >>> f.seek(0) # 调用seek方法,重置指针位置,这里是将指针定位于文件开头 0 >>> f.tell() # 指针位于文件开头 0 >>> f.read(5) # 重新读取文件前五个字符 'How t' >>> f.seek(22) # 调用seek方法,重置指针位置,这里是将指针定位于第22个字符后 22 >>> f.tell() 22
seek(offset[, whence])是这个函数的完整形式,以上我们忽略了whence,默认whence=0表示从文件开头计算指针偏移量。具体如下:
默认值为0,表示从文件开头计算指针偏移量。这时的offset必须大于或等于零的整数;
当whence=1时,表示从当前位置开始计算指针偏移量。如果offset是负数,表示从当前位置向前移动;如果offset是正数,表示向后移动;
当whence=2时,表示相对于文件末尾的移动。
需要注意的是,Python3不允许非二进制方式打开的文件,相对于指针当前位置或文件末尾的定位。就是说,如果想定位到指针当前位置或文件末尾,可以用python2.7或者在python3中用二进制的方式打开文档。
文件对象与迭代:文件对象是可迭代的对象。
判断一个对象是否可迭代的方法:
1. 使用dir()查看该对象的方法中是否有__iter__
>>> dir(list) ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
2. hasattr(obj, '__iter__')的布尔值
>>> hasattr(list, '__iter__') True
3. 使用collections标准库中的Iterable进行判断
>>> import collections >>> isinstance(321, collections.Iterable) False >>> isinstance('qwe', collections.Iterable) True
文件b的模式:
1. b模式下不能再指定encoding编码;
2. 字符串转化为二进制,必须要进行编码;
3. 字符串对象可直接调用encode()方法进行编码。
>>> '字符串'.encode('utf-8') b'\xe5\xad\x97\xe7\xac\xa6\xe4\xb8\xb2'
使用文件操作的其它注意方面:
- seek以字节为单位进行定位,在python2中可以直接用;而python3是以utf-8编码,所以在python3中使用seek的模式2和3时,要将文件以二进制的方法打开。
>>> f = open('test.py', 'rb') # 以二进制方式打开 >>> f.seek(16, 1) 16 >>> f.tell() 16 >>> f.seek(-5, 1) 11 >>> f.seek(-10, 2) 54 >>> f.seek(10, 2) 74
2. 一个汉字占三个字节,一个字符占一个字节
3. 循环文件的推荐方式:
f = open('test.txt') for line in f: # 循环一行给一行,相当于延迟迭代 pass 而尽量不要用这种方式: f = open('test.txt') for line in f.readlines(): # 先将所有的行取出放到内存中再循环 pass
4. 文件写入的类型必须是字符串类型;读取出来也全是字符串的形式;
5. with可以同时打开多个文件;
>>> with open('test.py') as f1,\ ... open('demo.txt', 'w') as f2: # with同时打开两个文件 ... data = f1.read() # 文件读取 ... f2.write(data) # 文件写入(备份) ... 50
6. 要确保文件得以关闭,可使用一条try/finally语句,并在finally语句中调用close;
with语句在写入文件时,到达该语句末尾时,将自动关闭文件,即便出现异常也是如此。
>>> try: ... f = open('test.py') ... f.read() ... finally: # finally中处理文件关闭 ... f.close() ... 'qwertgfdsxcvb\nqwe123432\n1234876543\n人生苦短,我用python!\n'
7. 使用print可以用来写入文件,相当于write方法。
8. print写入文件的方式:
f = open('filename', 'w') print('123456', 'qwertr', file=f) # 相当于连续执行f.write('123456')和f.write('qwertr\n')
文件模式
模式 |
说明 |
r |
以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
w |
打开一个文件只用于写入。如果该文件已存在则将其清空。如果该文件不存在,创建新文件。 |
a |
打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的 内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
rb |
以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
wb |
以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在, 创建新文件。 |
ab |
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。 也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
r+ |
打开一个文件用于读写。文件指针将会放在文件的开头。 |
w+ |
打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a+ |
打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会 是追加模式。如果该文件不存在,创建新文件用于读写。 |
rb+ |
以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
wb+ |
以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在, 创建新文件。 |
ab+ |
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。 如果该文件不存在,创建新文件用于读写。 |