返回介绍

IO 编程

发布于 2024-05-30 23:22:17 字数 18795 浏览 0 评论 0 收藏 0

文件读写

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文