文件读写 读写文件是最常见 的IO 操作。Python内置了读写文件的函数,用法和C是兼容的。 在读写文件之前,要了解,在磁盘上读写文件的功能都是由操作系统提供的 ,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作 系统打开一个文件对象(文件描述符),然后,通过操作系统提供的接口从这个文件 对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。
读文件 要以读文件模式打开一个文件对象,使用Python内置的open()函数,传入文件名和标识符:
>>>f = open('/Users/michael/test.txt', 'r')
标识符‘r’表示读,这样,我们就成功的打开了一个文件。 如果文件不存在,open()函数就会抛出一个IOError的错误,并且给出错误码和详细的信息告诉你文件不存在:
>>>f = open('C:\Users\Administrator\Desktop\question.txt'', 'r') 如果文件打开成功,接下来,调用read()方法可以一次读取文件的全部内容,Python把内容读到内存,用一个str对象表示:
>>> f = open(r'C:\Users\Administrator\Desktop\question.txt', 'r') 存下来就可以 >>> f.read() >>> f.close() 由于文件读写时都有可能 产生IOError,一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try…finally来实现。
try: f = open('/path/to/file', 'r') print(f.read()) finally: if f: f.close()结果:
但是每次都这么写太繁琐,所以,python引入了with语句来调用close()方法。
>>> with open(r'C:\Users\Administrator\Desktop\question.txt', 'r') as f: ... print(f.read())这和前面的try … finally是一样的,但是代码更简洁,并且不必调用f.close()方法 。 调用 read()会一次性读取文件的全部内容,如果文件有10G,内存就爆了,所以要时时调用read (size)判断。 readline()每次读取一行内容。 调用readlines()一次读取所有内容并按行返回list。 因此,要根据需要决定怎么调用。 如果文件很小,read()一次性读取最方便:
for line in f.readlines(): print(line.strip()) #把末尾的‘\n’删掉一品威客,猪八戒
file-like Object 像open()函数返回的这种有个read()方法的对象,在Python中统称为file-like Object。除了file外,还可以是内存的字节流,网络流,自定义流等等。file-like Object不要求从特定类继承,只要写个read()方法就行。 StringIO就是在内存中创建的file-like Object,常用作临时缓冲。
二进制文件
前面读取的都是文本文件,并且是UTF-8编码的文本文件。读取二进制文件,比如图片、视频等等,用‘rb’模式打开文件即可:
>>>f = open(r'C:\Users\Administrator\Desktop\question.txt', 'rb') >>> f.read() b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节字符编码 要读取非UTF-8编码的文本文件,需要给open()函数传入encoding参数。 例如,读取GBK编码的文件:
>>>f = open(r'C:\Users\Administrator\Desktop\question.txt', 'r', encoding='gbk') >>>f.read()遇到有些编码不规范的文件,你可能会遇到UnicodeDecodeError,因为在文本文件中可能夹杂了 一些非法编码的字符。 遇到这种情况,open()函数还接收一个error参数,表示如果遇到编码错误后如何处理。 最简单的方式是直接忽略:
>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')
写文件 与读文件一样,唯一区别是调用open()函数时,传入标识符‘w’或者‘wb’表示写文本文件或写二进制文件:
>>> f = open('C:\Users\Administrator\Desktop\question.txt', 'w') >>> f.write('Hello, world!') >>> f.close()当写文件时,操作系统不会立刻把数据 写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用close()的后果是可能只写了一部分剩下的丢失。 或者这样用with写,更保险:
>>> with open(r'C:\Users\Administrator\Desktop\question.txt', 'w') as f: ... f.write('Hello,worlbvbvcd') ... 16要写入特定编码的文本文件,要给open()函数传入encoding参数,将字符串自动转换成指定编码。 以‘w’模式写入文件时,如果文件已存在,会直接覆盖(相当于删掉后新写入一个文件 )。如果 我们希望追加到文件末尾怎么办? 可以传入‘a’以追加 (append)模式写入。 内置函数:https://docs.python.org/3/library/functions.html#open
StringIO 数据读写不一定是文件,也可以在内存中读写。 StringIO就是在内存中读写str。 要把str写入StringIO,我们需要先创建一个StringIO,然后,像文件一样写入即可:
from io import StringIO f = StringIO() f.write('hello') f.write(' ') f.write('world!') print(f.getvalue())getvalue()方法用于获得写入后的str 要读取StringIO,可以用一个str初始化StringIO,然后像文件一样读取:
from io import StringIO #从IO中导入StringIO f = StringIO('Hello!\n Hi!\n Goodbye') #吧string存到内存中 while True: s = f.readline() if s =='': #如果下一行为空 break print(s.strip())结果: BytesIO StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。 BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes:
from io import BytesIO #从IO中导入BytesIO f = BytesIO() #像文件一样对内存空间进行操作 f.write('中文'.encode('utf-8')) #写入 print(f.getvalue())结果: StringIO和BytesIO是在内存中操作str和bytes的方法,使得和读写文件具有一致的接口。
操作文件和目录 如果我们要操作文件、目录,可以在命令行下面输入操作系统提供的各种命令来完成。比如dir、cp等命令。 如果要在Python程序中执行这些目录的文件的操作怎么办?其实操作系统提供的命令只是简单的调用了操作系统提供的接口函数,Python内置的OS模块也可以直接调用操作系统提供的接口函数。 打开Python交互式命令行,我们来看看如何使用os模块的基本功能: import os print(os.name) 输出:nt 如果是posix,说明系统是Linux、Unix或Mac OS X,如果是nt,就是Windows系统。 要获取详细的系统信息,可以调用uname()函数:
>>> os.uname() posix.uname_result(sysname='Darwin', nodename='MichaelMacPro.local', release='14.3.0', version='Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64', machine='x86_64')但是这个uname()属性我Windows上没有,os模块的某些函数是跟操作系统相关的。
在操作系统中定义的环境变量,全部保存在os.environ这个变量中,可以直接查看:
print(os.environ) 我的环境变量好长一串啊!
environ({'ALLUSERSPROFILE': 'C:\\ProgramData', 'APPDATA': 'C:\\Users\\Administrator\\AppData\\Roaming', 'COMMONPROGRAMFILES': 'C:\\Program Files\\Common Files', 'COMMONPROGRAMFILES(X86)': 'C:\\Program Files (x86)\\Common Files', 'COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files', 'COMPUTERNAME': 'SKY-20200609OSE', 'COMSPEC': 'C:\\Windows\\system32\\cmd.exe', 'CONDA_SHLVL': '0', 'DRIVERDATA': 'C:\\Windows\\System32\\Drivers\\DriverData', 'HOMEDRIVE': 'C:', 'HOMEPATH': '\\Users\\Administrator', 'IDEA_INITIAL_DIRECTORY': 'C:\\Users\\Administrator\\Desktop', 'LOCALAPPDATA': 'C:\\Users\\Administrator\\AppData\\Local', 'LOGONSERVER': '\\\\SKY-20200609OSE', 'NUMBER_OF_PROCESSORS': '4', 'OS': 'Windows_NT', 'PATH': 'G:\\zrx\\demoproject\\venv\\Scripts;G:\\zrx\\Anaconda3\\condabin;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Windows\\System32\\OpenSSH\\;D:\\Program Files\\Git\\cmd;D:\\Program Files\\TortoiseGit\\bin;D:\\Program Files\\PuTTY\\;D:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\;D:\\Program Files (x86)\\Microsoft SQL Server\\100\\DTS\\Binn\\;D:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\VSShell\\Common7\\IDE\\;C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\Common7\\IDE\\PrivateAssemblies\\;D:\\phpstudy\\Extensions\\php\\php7.3.4nts\\;G:\\zrx\\Anaconda3;G:\\zrx\\Anaconda3\\Scripts;G:\\zrx\\python\\Scripts;C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\WindowsApps;', 'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC', 'PROCESSOR_ARCHITECTURE': 'AMD64', 'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 94 Stepping 3, GenuineIntel', 'PROCESSOR_LEVEL': '6', 'PROCESSOR_REVISION': '5e03', 'PROGRAMDATA': 'C:\\ProgramData', 'PROGRAMFILES': 'C:\\Program Files', 'PROGRAMFILES(X86)': 'C:\\Program Files (x86)', 'PROGRAMW6432': 'C:\\Program Files', 'PROMPT': '(venv) $P$G', 'PSMODULEPATH': 'C:\\Program Files\\WindowsPowerShell\\Modules;C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules', 'PUBLIC': 'C:\\Users\\Public', 'PYCHARM_HOSTED': '1', 'PYTHONIOENCODING': 'UTF-8', 'PYTHONPATH': 'G:\\zrx\\demoproject', 'PYTHONUNBUFFERED': '1', 'SESSIONNAME': 'Console', 'SYSTEMDRIVE': 'C:', 'SYSTEMROOT': 'C:\\Windows', 'TEMP': 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp', 'TMP': 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp', 'USERDOMAIN': 'SKY-20200609OSE', 'USERDOMAIN_ROAMINGPROFILE': 'SKY-20200609OSE', 'USERNAME': 'Administrator', 'USERPROFILE': 'C:\\Users\\Administrator', 'VIRTUAL_ENV': 'G:\\zrx\\demoproject\\venv', 'WINDIR': 'C:\\Windows', '_OLD_VIRTUAL_PATH': 'G:\\zrx\\Anaconda3\\condabin;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Windows\\System32\\OpenSSH\\;D:\\Program Files\\Git\\cmd;D:\\Program Files\\TortoiseGit\\bin;D:\\Program Files\\PuTTY\\;D:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\;D:\\Program Files (x86)\\Microsoft SQL Server\\100\\DTS\\Binn\\;D:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\VSShell\\Common7\\IDE\\;C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\Common7\\IDE\\PrivateAssemblies\\;D:\\phpstudy\\Extensions\\php\\php7.3.4nts\\;G:\\zrx\\Anaconda3;G:\\zrx\\Anaconda3\\Scripts;G:\\zrx\\python\\Scripts;C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\WindowsApps;', '_OLD_VIRTUAL_PROMPT': '$P$G'})要获取某个环境变量的值,可以调用os.environ.get(‘key’):
>>> os.environ.get('PATH') 'G:\zrx\demoproject\venv\Scripts;G:\zrx\Anaconda3\condabin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;D:\Program Files\Git\cmd;D:\Program Files\TortoiseGit\bin;D:\Program Files\PuTTY\;D:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;D:\Program Files (x86)\Microsoft SQL Server\100\DTS\Binn\;D:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\;C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\;D:\phpstudy\Extensions\php\php7.3.4nts\;G:\zrx\Anaconda3;G:\zrx\Anaconda3\Scripts;G:\zrx\python\Scripts;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;' >>> print(os.environ.get('x', 'default')) 'default'操作文件和目录 操作文件和目录的函数一部分放在os模块中,一部分放在os.path模块中,这一点要注意一下。查看、创建和删除目录可以这么调用: #查看当前目录的绝对路径 print(os.path.abspath('.')) #在某个目录下创建一个新目录,首先把新目录的完整路径表示出来: os.