只读模式(默认) 文件必须存在
只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
创建并写入一个新文件, 文件存在会报异常
以附加的方式打开只写文件。
若文件不存在,则会建立该文件,并在尾部追加
如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。
字节流,将文件就按照字节理解,与字符编码无关,二进制模式操作时,字节操作用bytes类型
字符流,将文件的字节按照某种字符编码理解,按照字符操作
打开可读写的文件,该文件必须存在
可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。
"U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)
表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)
读取二进制文件
with open('Rick.jpg', 'rb') as f: data = f.read() print(type(data))
with open('Rick.jpg', 'wb') as e: e.write(data)
打印光标位置
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
-1表示缺省大小的buffer
如果是二进制模式,使用io.DEFAULT_BUFFER_SIZE值,默认为4096或者8192
仅文本模式使用
None表示缺省编码,Linux为UTF-8
None和strict表示有编码错误,将抛出ValueError异常
换行转换,\r, \n. \r\n
读时,None表示\r, \n, \r\n都被转换为\n,表示不会自动转换通用换行符,其他合法字符表示换行符就是指定字符,就会按照指定字符分行
写时,None表示\n都会被替换为缺省行分隔符os.linesep; 其他合法字符表示\n会被替换为指定的字符
关闭文件描述符,True表示关闭,False会在文件关闭后保持这个描述符
读取每行的内容
读取整个文件,生成列表
文件内容替换
for line in fileinput.input('filepath', inplace=1): line = line.replace('oldtext', 'newtext') print(line)
修改某行
with open('foo.txt', 'r++') as f: old = f.read() f.seek(0) f.write('new line\n' + old) line before
写入
f.write('I like apple!\n') # 将'I like apple'写入文件并换行
关闭前会调用flush()
f.close() #关闭文件
移动文件指针位置,offset偏移多少字节,whence从哪里开始
seek(offset[, whence])
刷新缓冲,即将缓冲区的数据写入磁盘
f = open('test.txt', 'w') f.write('hello1\n') f.flush() f.write('hello2\n')
实时生成进度条
import sys, time for i in range(20): sys.stdout.write('#'); sys.stdout.flush() time.sleep(0.2)
为了避免打开文件后忘记关闭,可以通过管理上下文,即:
with open('log','r') as f: pass
如此方式,当with代码块执行完毕时,内部会自动关闭并释放文件资源。
在Python 2.7 后,with又支持同时对多个文件的上下文进行管理,即:
with open('log1') as obj1, open('log2') as obj2: pass
只要对象中实现了__enter__
和 __exit__
就可以使用with 语句
class A: def __enter__(self): a = 1 return a def __exit__(self): b = 2 with A() as obj_a: pass
通过debug 模式,obj_a是返回
__enter__
的返回值, 但是一旦执行了__exit__
结束了上下文管理
class MyResource: def __enter__(self): print('Connect to resource') return self def __exit__(self, exc_type, exc_val, exc_tb): print('Disconnect to resource') def query(self): print('Query data') with MyResource() as resource: resource.query() >>> Connect to resource Query data Disconnect to resource
d = {} with open('sample', encoding='utf-8') as f: for line in f: words = line.split() for word in map(str.lower, words): d[word] = d.get(word, 0) + 1 print(sorted(d.item(), key=lambda item: item[1], reverse=True))
基于类的上下文管理器更加 flexible,适用于大型的系统开发
class FileManager: def __init__(self, name, mode): print('calling __init__ method') self.name = name self.mode = mode self.file = None def __enter__(self): print('calling __enter__ method') self.file = open(self.name, self.mode) return self.file def __exit__(self, exc_type, exc_val, exc_tb): print('calling __exit__ method') if self.file: self.file.close() with FileManager('test.txt', 'w') as f: print('ready to write to file') f.write('hello world') >>> calling __init__ method calling __enter__ method ready to write to file calling __exit__ method
用类来创建上下文管理器时,必须保证这个类包括方法
”__enter__()”
和方法“__exit__()”
。其中,方法“__enter__()”
返回需要被管理的资源,方法“__exit__()”
里通常会存在一些释放、清理资源的操作,比如这个例子中的关闭文件等等如果你需要处理可能发生的异常,可以在
“__exit__()”
添加相应的代码,可以自行定义相关的操作对异常进行处理,而处理完异常后,也别忘了加上“return True”
这条语句,否则仍然会抛出异常
class Foo: def __init__(self): print('__init__ called') def __enter__(self): print('__enter__ called') return self def __exit__(self, exc_type, exc_value, exc_tb): print('__exit__ called') if exc_type: print(f'exc_type: {exc_type}') print(f'exc_value: {exc_value}') print(f'exc_traceback: {exc_tb}') print('exception handled') return True with Foo() as obj: raise Exception('exception raised').with_traceback(None) >>> __init__ called __enter__ called __exit__ called exc_type: <class 'Exception'> exc_value: exception raised exc_traceback: <traceback object at 0x1046036c8> exception handled
class DBConnectionManager: def __init__(self, hostname, port): self.hostname = hostname self.port = port self.connection = None def __enter__(self): self.connection = DBClient(self.hostname, self.port) return self def __exit__(self, exc_type, exc_val, exc_tb): self.connection.close() with DBConnectionManager('localhost', '8080') as db_client:
方法
“__init__()”
负责对数据库进行初始化,也就是将主机名、接口(这里是 localhost 和 8080)分别赋予变量 hostname 和 port;方法
“__enter__()”
连接数据库,并且返回对象 DBConnectionManager;方法
“__exit__()”
则负责关闭数据库的连接。
基于生成器的上下文管理器更加方便、简洁,适用于中小型程序
使用装饰器 contextlib.contextmanager,来定义自己所需的基于生成器的上下文管理器,用以支持 with 语句。
from contextlib import contextmanager @contextmanager def file_manager(name, mode): try: f = open(name, mode) yield f finally: f.close() with file_manager('test.txt', 'w') as f: f.write('Hello World')
函数 file_manager() 是一个生成器,当我们执行 with 语句时,便会打开文件,并返回文件对象 f;当 with 语句执行完后,finally block 中的关闭文件操作便会执行。