前言
文件操作还不会吗,面试的时候问到上下文管理还一脸懵逼?来不及了呀,赶快看,下次再有人问你的时候不用尴尬而不失礼貌的微笑了。
一、文件的访问模式
在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件。
# open(文件名,访问模式)
file = open('test.txt', 'w')
这里是常用的读写模式,我简单的整理了一下。
访问模式 | 说明 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
二、简单的操作文件
1.打开文件
# 如有文件直接打开,没有文件会新建一个文件
file = open('test.txt', 'w')
这里要注意一下,打开文件的模式会影响接下来的操作。
2.写入数据
file.write("hello world")
3.读取数据
# read(num)
# num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据
content = f.read()
文件很大的时候切记要少量多次
4.关闭文件
file.close()
三、with与“上下文管理器”
对于系统资源如文件、数据库连接、socket 而言,应用程序打开这些资源并执行完业务逻辑之后,必须做的一件事就是要关闭(断开)该资源。但是有时候发生异常后就会出现无法关闭,所以我们要做一些异常处理。
1.进阶版
def test():
f = open("output.txt", "w")
try:
f.write("python")
except IOError:
print("oops error")
finally:
f.close()
这样倒是可以满足需求,不管发生什么文件一定会关闭,但是还有没有更好的办法呢?
2.高级版
def test():
with open("output.txt", "r") as f:
f.write("python")
一种更加简洁、优雅的方式就是用 with 关键字。open 方法的返回值赋值给变量 f,当离开 with 代码块的时候,系统能够自动调用 f.close() 方法。
3.上下文管理
任何实现了 enter() 和 exit() 方法的对象都可称之为上下文管理器,上下文管理器对象可以使用 with 关键字。显然,文件(file)对象也实现了上下文管理器。
那么文件对象是如何实现这两个方法的呢?我们可以模拟实现一个自己的文件类,让该类实现 enter() 和 exit() 方法。
class File():
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
print("entering")
self.f = open(self.filename, self.mode)
return self.f
def __exit__(self, *args):
print("will exit")
self.f.close()
enter() 方法返回资源对象,这里就是你将要打开的那个文件对象,exit() 方法处理一些清除工作。
因为 File 类实现了上下文管理器,现在就可以使用 with 语句了。现在是不是感觉清楚多了。
总结
剩下的要做的就简单多了,我们可以把读取任何文件进行传输(图片,文本,文件夹,表格…),另存或者通过网络请求发送给指定用户,是不是很强大呀!