IO 编程
文件读写
Python 内置了读写文件的函数,用法和C 是兼容的。 以下内容没有特别说明则默认是读取文本文件,并且是 UTF-8 编码的文本文件。
file-like Object
像 open()函数返回的这种有个 read()方法的对象,在 Python 中统称为file-like Object
。
除了 file 外,还可以是内存的字节流,网络流,自定义流等等。file-like Object
不要求从特定类继承,只要写个 read()
方法就行。
读文本文件
例如:
f = open('/Users/test.txt', 'r') #如果文件不存在, open()函数就会抛出一个 IOError 的错误
s = f.read() #调用 read()方法一次性读取所有的内容到内存,返回一个str对象
print(s)
f.close() #关闭文件
注: 调用 read()会一次性读取文件的全部内容,并返回str; 调用 read(size)每次最多读取size个字节的内容,并返回str; 调用 readline()每次读取一行内容,并返回str; 调用 readlines()会一次性读取所有内容,并按行返回 list; 如果文件很小, read()一次性读取最方便;如果不能确定文件大小,反复调用 read(size)比较保险;如果是配置文件,调用 readlines()最方便。
字符编码
要读取非 UTF-8 编码的文本文件,需要给 open()
函数传入 encoding 参数,例如,读取 GBK 编码的文件:
>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk')
>>> f.read()
'测试'
遇到有些编码不规范的文件,你可能会遇到 UnicodeDecodeError,因为在文本文件中可能夹杂了一些非法编码的字符。遇到这种情况, open()
函数还接收一个 errors 参数,表示如果遇到编码错误后如何处理。最简单的方式是直接忽略:
>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk',errors='ignore')
读二进制文件
要读取二进制文件,比如图片、视频等等,用'rb'
模式打开文件即可。
例如:
>>> f = open('/Users/michael/test.jpg', 'rb')
>>> f.read()
b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节
写文件
传入标识符'w'
或者'wb'
分别表示写文本文件和写二进制文件。
例如:
with open('/Users/michael/test.txt', 'w') as f:
f.write('Hello, world!')
StringIO 和 BytesIO
StringIO 和 BytesIO 是在内存中操作 str 和 bytes 的方法,它和读写文件具有一致的接口。
StringIO
StringIO 顾名思义就是在内存中读写 str。
首先需要创建一个 StringIO,然后,像文件一样写入即可:
from io import StringIO
f1 = StringIO()
f1.write('hello')
print(f1.getvalue()) #getvalue()方法用于获得写入后的 str。
f1.close()
f2 = StringIO('Hello!\nHi!\nGoodbye!')
s = f2.readline()
f2.close()
BytesIO
BytesIO是在内存中读写二进制数据。
>>> from io import BytesIO
>>> f1 = BytesIO()
>>> f1.write('中文'.encode('utf-8'))
6
>>> print(f.getvalue()) #getvalue()方法用于获得写入后的 str。
b'\xe4\xb8\xad\xe6\x96\x87'
>>> f1.close()
>>> f2 = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
>>> f2.read()
b'\xe4\xb8\xad\xe6\x96\x87'
>>> f2.close()
操作文件和目录
Python 内置的 os 模块可以直接调用操作系统提供的接口函数。需要注意os 模块的某些函数是跟操作系统相关的。
>>> import os
>>> os.name
'posix'
查看操作系统类型。如果输出是 posix,则是 Linux、Unix 或 Mac OS X;如果是 nt,则是 Windows。
要获取详细的系统信息,可以调用 uname()函数:
>>> os.uname() #注意 uname()函数在 Windows 上不提供
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')
环境变量
在操作系统中定义的环境变量,全部保存在 os.environ 这个变量中,可以直接查看:
>>> os.environ
要获取某个环境变量的值,可以调用 os.environ.get('变量名'):
>>> os.environ.get('PATH')
操作文件和目录
查看当前目录的绝对路径:
>>> os.path.abspath('.')
'/Users/michael'
把两个路径合成一个:
>>> os.path.join('/Users/michael', 'testdir')
'/Users/michael/testdir'
创建和删除目录:
>>> os.mkdir('/Users/michael/testdir')
>>> os.rmdir('/Users/michael/testdir')
把一个路径拆分为两部分,后一部分是最后级别的目录或文件名:
>>> os.path.split('/Users/michael/testdir/file.txt')
('/Users/michael/testdir', 'file.txt')
得到文件扩展名:
>>> os.path.splitext('/path/to/file.txt')
('/path/to/file', '.txt')
[注]这些合并、拆分路径的函数并不要求目录和文件要真实存在,它们只对字符串进行操作。
对文件重命名:
>>> os.rename('test.txt', 'test.py')
删掉文件:
>>> os.remove('test.py')
列出当前目录下的所有文件和目录:
>>> os.listdir('.')
判断是否是一个目录:
>>> os.path.isdir('test.py')
判断是否是一个文件:
>>> os.path.isdir('test.py')
举例:
#列出所有的.py 文件
[x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']
序列化
把变量从内存中变成可存储或传输的过程称之为序列化,在 Python中叫 pickling。序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。
把变量内容从序列化的对象重新读到内存里称之为反序列化,即 unpickling。
pickle 模块
pickle.dumps()
方法把任意对象序列化成一个 bytes,然后,就可以把这个 bytes 写入文件。
例如:
>>> import pickle
>>> d = dict(name='Bob', age=20, score=88)
>>> pickle.dumps(d)
b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x14X\x05\x00\x00\x00score
q\x02KXX\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Bobq\x04u.'
或者用另一个方法 pickle.dump()
直接把对象序列化后写入一个 file-like Object
:
f = open('dump.txt', 'wb')
pickle.dump(d, f)
f.close()
当我们要把对象从磁盘读到内存时,可以先把内容读到一个 bytes,然后用 pickle.loads()
方法反序列化出对象,也可以直接用 pickle.load()
方法从一个 file-like Object
中直接反序列化出对象:
>>> f = open('dump.txt', 'rb')
>>> d = pickle.load(f)
>>> f.close()
>>> d
{'age': 20, 'score': 88, 'name': 'Bob'}
[注]Pickle是Python特有的。Pickle 的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于 Python,并且可能不同版本的 Python 彼此都不兼容,因此,只能用 Pickle 保存那些不重要的数据,不能成功地反序列化也没关系。
JSON
如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如 XML,但更好的方法是序列化为 JSON, 因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。 JSON 不仅是标准格式,并且比 XML 更快,而且可以直接在 Web 页面中读取,非常方便。
JSON 表示的对象就是标准的 JavaScript 语言的对象, JSON 和 Python内置的数据类型对应如下:
JSON类型 Python类型
{} dict
[] list
"string" str
1234.56 int 或 float
true/false True/False
null None
Python 内置的 json 模块提供了非常完善的 Python 对象到 JSON 格式的转换。我们先看看如何把 Python 对象变成一个 JSON:
>>> import json
>>> d = dict(name='Bob', age=20, score=88)
>>> json.dumps(d)
'{"age": 20, "score": 88, "name": "Bob"}'
dumps()
方法返回一个 str,内容就是标准的 JSON。类似的, dump()
方法可以直接把 JSON 写入一个 file-like Object
。
要把 JSON 反序列化为 Python 对象,用 loads()
或者对应的 load()
方法,前者把 JSON 的字符串反序列化,后者从 file-like Object
中读取字符串并反序列化:
>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}'
>>> json.loads(json_str)
{'age': 20, 'score': 88, 'name': 'Bob'}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论