给Python初学者的文件读写指南(含基础与进阶,建议收藏)
-
如何将列表数据写入文件?
-
如何从文件中读取内容?
-
多样需求的读写任务
-
从with语句到上下文管理器
如何将列表数据写入文件?
li = ['python',' is',' a',' cat']
with open('test.txt','w') as f:
f.write(li)
TypeError Traceback (most recent call last)
<ipython-input-6-57e0c2f5a453> in <module>()
1 with open('test.txt','w') as f:
----> 2 f.write(li)
TypeError: write() argument must be str, not list
# 以下3种写法等价,都是写入字符串“python is a cat”
In [20]: with open('test.txt','w') as f:
...: f.writelines(['python',' is',' a',' cat'])
...: f.writelines('python is a cat')
...: f.write('python is a cat')
# 以下2种写法等价,都是写入列表的字符串版本“['python',' is',' a',' cat']”
In [21]: with open('test.txt','w') as f:
...: f.write(str(['python',' is',' a',' cat']))
...: f.writelines(str(['python',' is',' a',' cat']))
# 作为反例,以下写法都是错误的:
In [22]: with open('test.txt','w') as f:
...: f.writelines([2018,'is','a','cat']) # 含非字符串
...: f.write(['python','is','a','cat']) # 非字符串
In [37]: content=[1,' is',' everything']
In [38]: with open('test.txt','w') as f:
...: for i in content:
...: f.write(str(i))
如何从文件中读取内容?
file.read([size]) 从文件读取指定的字节数,如果未给定或为负则读取所有。
file.readline([size]) 读取整行,包括 “\n” 字符。
file.readlines([sizeint]) 读取所有行并返回列表,若给定sizeint>0,则是设置一次读多少字节,这是为了减轻读取压力。
In [47]: with open('test.txt','r') as f:
...: print(f.read())
1 is everything.
python is a cat.
this is the end.
In [48]: with open('test.txt','r') as f:
...: print(f.readlines())
['1 is everything.\n', 'python is a cat.\n', 'this is the end.']
In [49]: with open('test.txt','r') as f:
...: print(f.readline())
1 is everything.
In [61]: with open('test.txt','r') as f:
...: for line in f.readlines():
...: print(line)
1 is everything.
python is a cat.
this is the end.
# 读取内容包含换行符,所以要strip()去掉换行符
In [62]: with open('test.txt','r') as f:
...: for line in f.readlines():
...: print(line.strip())
1 is everything.
python is a cat.
this is the end.
多样需求的读写任务
open(file, mode=‘r’, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
In [63]: with open('test.txt','r') as f:
...: for line in f.readlines():
...: print(line.strip())
-----------------------
UnicodeDecodeError Traceback (most recent call last)
<ipython-input-63-731a4f9cf707> in <module>()
1 with open('test.txt','r') as f:
----> 2 for line in f.readlines():
3 print(line.strip())
UnicodeDecodeError: 'gbk' codec can't decode byte 0xa4 in position 26: illegal multibyte sequence
In [65]: with open('test.txt','r',encoding='utf-8') as f:
...: for line in f.readlines():
...: print(line.strip())
爱猫猫
python is a cat.
‘r’: 以只读模式打开(缺省模式)(必须保证文件存在)
‘w’:以只写模式打开。若文件存在,则清空文件,然后重新创建;若不存在,则新建文件。
‘a’:以追加模式打开。若文件存在,则会追加到文件的末尾;若文件不存在,则新建文件。
常见的mode组合
‘r’或’rt’: 默认模式,文本读模式
‘w’或’wt’: 以文本写模式打开(打开前文件会被清空)
‘rb’: 以二进制读模式打开
‘ab’: 以二进制追加模式打开
‘wb’: 以二进制写模式打开(打开前文件会被清空)
‘r+’: 以文本读写模式打开,默认写的指针开始指在文件开头, 因此会覆写文件
‘w+’: 以文本读写模式打开(打开前文件会被清空)
‘a+’: 以文本读写模式打开(写只能写在文件末尾)
‘rb+’: 以二进制读写模式打开
‘wb+’: 以二进制读写模式打开(打开前文件会被清空)
‘ab+’: 以二进制读写模式打开
从with语句到上下文管理器
# 不用with语句的正确写法
try:
f = open('test.txt','w')
f.writelines(['python',' is',' a',' cat'])
finally:
if f:
f.close()
# 使用with语句的正确写法
with open('test.txt','w') as f:
f.writelines(['python',' is',' a',' cat'])
上下文管理器是这样一个对象:它定义程序运行时需要建立的上下文,处理程序的进入和退出,实现了上下文管理协议,即在对象中定义了 __enter__() 和 __exit__() 方法。 __enter__():进入运行时的上下文,返回运行时上下文相关的对象,with 语句中会将这个返回值绑定到目标对象。 __exit__(exception_type, exception_value, traceback):退出运行时的上下文,定义在块执行(或终止)之后上下文管理器应该做什么。它可以处理异常、清理现场或者处理 with 块中语句执行完成之后需要处理的动作。
class OpenFile(object):
def __init__(self,filename,mode):
self.filename=filename
self.mode=mode
def __enter__(self):
self.f=open(self.filename,self.mode)
self.f.write("enter now\n")
return self.f #作为as说明符指定的变量的值
def __exit__(self,type,value,tb):
self.f.write("exit now")
self.f.close()
return False #异常会被传递出上下文
with OpenFile('test.txt','w') as f:
f.write('Hello World!\n')
enter now Hello World! exit now
from contextlib import contextmanager
@contextmanager
def open_file(name):
ff = open(name, 'w')
ff.write("enter now\n")
try:
yield ff
except RuntimeError:
pass
ff.write("exit now")
ff.close()
with open_file('test.txt') as f:
f.write('Hello World!\n')