python中,当使用open函数打开一个文件时,可以通过mode参数指定打开的模式,以下是一个大概的对模式的总结和说明。
'r': 读取模式(默认),需要文件已经存在;
'w': 写入模式,如果原文件已经存在,会覆盖原文件的内容;
'x': 创建一个新的文件,如果文件已经存在,则会报错,该模式下,只可写入,不可读取;
'a': 该模式为追加写入模式,即如果文件已经存在,则在原文件内容后面追加写入,不会覆盖原文件内容;
'b': 二进制模式,一般和读写模式相结合使用,如'wb','rb';
't': 文本模式(默认),一般和读写模式相结合使用,如'wt','rt',读写模式默认为文本读写模式;
'+': 该模式为更新模式,既文件对象将同时有读和写的方法。其必须和'r'、'w'、'a'、'x'之一结合使用,不可单独使用。'w+'下,写入操作时,会覆盖原文件内容;若不想覆盖原文件内容,可以在'a+'模式下打开文件,这样写入时就是追加写入;'r+'模式下,既可以读取原文件内容,也可以在文件末尾追加写入内容,文件若不存在,则会报错,而在'w+'模式下,文件不存在则会先创建文件。要注意的是,’a+'模式下,文件默认的光标在文件末尾,所以直接读取将无法获取内容,可以通过f.seek(num)方法将光标移动到指定的字节处,然后读取便可以读到内容。对于readline()、write()方法,若想指定位置读取或写入,都需要提前通过seek()方法移动光标,不然会以默认位置读取和写入,readline默认文件开始并逐步向后移动,而write默认文件末尾。
mode参数必须要有'a','r','w','x'之一,以及最多一个'+’。
下面主要对文本模式和二进制模式进行说明。
如果是在二进制模式下读写,在写入时,需要写入的是字节码,而不能是字符串,所以如果是字符串,需要先进行编码,这时就会依赖于特定的编码方式,然后写入到文件中后,将会直接写入编码后的字节码;如果我们要在系统中打开文件,那么编辑器也必须以程序中相应的编码方式打开文件,不然会出现乱码或者无法打开。比如,python3中默认的编码方式是utf8,那么当以默认编码方式编码字符串并以二进制写入文件,那么要在系统中打开该文件,相应的编辑器也应该以utf8编码方式才可以正常打开。在以二进制模式读取时,将也是直接读取文件中的字节码,这时并不需要进行字节码到字符串的转换,所以也不涉及编码问题,但是在读取之后,如果要进一步对字节码进行解码,那么就要知道其对应的编码方式。比如,如果是以utf8编码方式将编码后的字节码写入文件的话,那么在读取后,也要以utf8编码方式来解码读取的字节码才可以得到字符串。可知,在以二进制模式读写时,并不会涉及到系统的编码方式,只有将要在系统中打开文件时,才需要知道该文件是什么编码方式,然后指定编码方式才可以正常打开该文件。
如果是在文本模式下,在写入时,写入的对象需要是字符串,而不能是字节码,由于最终写入到文件中储存起来的还是字节码,所以这里就涉及到一个编码问题。如果创建文件对象时没有指定编码方式,那么写入时会根据电脑系统默认的编码方式对字符串进行编码后写入,比如windows下是gbk编码,那么文件最终就是以gbk编码的,在linux下是utf8,那么文件最终就是以utf8编码的;所以这时如果在打开文件时没有指定编码方式,写入时的编码方式是和系统平台的编码方式相关的。在读取时也是一样的,在文本模式下,打开文件读取后,返回的对象是字符串,不同于二进制模式下返回的字节码对象,所以这时也涉及到编码方式的问题;如果在创建文件对象时没有指定编码方式,那么python会用系统默认的编码方式去把文件里的字节码解码成字符串,如果指定了编码方式,那么程序就会用指定的编码方式去解码。综上,可知在文本模式下,读写时涉及了字符串和字节码之间的编码转换,因此如果我们没有指定编码方式,就需要知道系统的编码方式,以正确的实现编码转换。
综上,在二进制模式下,读写的都是字节码对象,不涉及程序和系统之间的编码转换过程,只有在程序内把字节码和字符串之间的转换需要编码解码;在文本模式下,读写的对象都是字符串,而因为文件保存的对象是以字节码形式保存的,所以在读写时涉及编码转换,而这时如果没有在创建文件对象时显式指定编码方式,读写时都会以系统平台默认的编码方式进行编码和解码,这里是需要注意的地方,不然容易引起编码问题。