【Python】编程笔记8

IO编程

通常,程序完成 IO 操作会有 Input 和 Output 两个数据流。Input Stream 就是数据从外面(磁盘、网络)流进内存, Output Stream 就是数据从内存流到外面去。

分类:同步IO、异步IO。区别就在于是否等待 IO 执行的结果。

异步 IO 来编写程序性能会远远高于同步 IO,但是异步 IO
的缺点是编程模型复杂。

一、文件读写

读写文件:请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。

1、读文件

步骤:open()、read()、close()

(1)open()

open() 函数传入文件名和标示符。其中,r 表示只读。

f = open('E:\codes\python\basic\1.py', 'r')

==》若文件不存在,则抛出 IOError 错误。

(2)read()

调用 read() 方法可一次读取文件的全部内容到内存中,用一个 str 对象表示。

f.read()
(3)close()

关闭文件——close() 方法
==》文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的。

f.close()
(4)try…finally实现

避免产生IOError的错误,而导致后面close()无法调用。

try:
    f = open('E:\\codes\\python\\basic\\1.txt', 'r')
    print(f.read())
finally:
    if f:
        f.close()
(5)with 语句(强烈推荐)

简洁、不用 f.close() 方法

with open('E:\\codes\\python\\basic\\1.txt', 'r') as f:
    print(f.read())
(6)注意
  • 若文件大,直接调用 read() 会导致内存爆掉==》read(size)方法,每次最多读取 size 个字节的内容;
  • readline() 函数:每次读取一行内容;
  • readlines() 函数:一次读取所有内容并按行返回 list;
(7)二进制文件

二进制文件:图片、视频等等==》‘rb’模式打开文件

f = open('/Users/michael/test.jpg', 'rb')
f.read()
# b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节
(8)字符编码——encoding、errors

读取 GBK 编码的文件。==》encoding = ‘gbk’

当遇到 UnicodeDecodeError (文件中夹杂一些非法编码的字符)==》errors = ‘ignore’,也就是忽略编码错误。

f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')

2、写文件

(1)基本

open() 函数,标示符为 ‘w’ 或 ‘wb’,表示写文本文件或写二进制文件。

f = open('/Users/michael/test.txt', 'w')
f.write('Hello, world!')
f.close()

注意:写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用 close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。

(2)with 语句

可以使用 encoding 参数设置指定的编码。

with open('/Users/michael/test.txt', 'w') as f:
	f.write('Hello, world!')

二、StringIO 和 BytesIO

1、StringIO

表示在内存中读写 str。

from io import StringIO
#### 写入
f = StringIO()
print(f.write('hello'))
print(f.write(' '))
print(f.write('world!'))
# getvalue(): 获得写入后的 str
print(f.getvalue())

#### 读取
f = StringIO('Hello!\nHi!\nGoodbye!')
while True:
    s = f.readline()
    if s == '':
        break
    print(s.strip())

输出结果

5
1
6
hello world!
Hello!
Hi!
Goodbye!

2、BytesIO

表示在内存中读写 二进制数据。

from io import BytesIO
### 写入
f = BytesIO()
print(f.write('中文'.encode('utf-8')))
print(f.getvalue())

### 读取
f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
print(f.read())

输出结果

6
b'\xe4\xb8\xad\xe6\x96\x87'
b'\xe4\xb8\xad\xe6\x96\x87'

三、操作文件和目录

模块:os
注意:os 模块的某些函数是跟操作系统相关的

1、系统属性信息

import os
print(os.name)                  # 操作系统类型
# uname()在 Linux 有,Windows 没有
# print(os.uname())   			# 获取详细的系统信息
print(os.environ)               # 环境变量
print(os.environ.get('PATH'))   # 获取某个环境变量的值

2、操作文件和目录

在 os 模块 和 os.path 模块中 + shutil 模块

print(os.path.abspath('.'))     # 查看当前目录的绝对路径
# 在某个目录下创建一个新目录,首先把新目录的完整路径表示出来
print(os.path.join('E:\codes\python\\basic', 'testdir'))
## 创建一个目录
os.mkdir('E:\codes\python\\basic\\1')
## 删除一个目录
os.rmdir('E:\codes\python\\basic\\1')
# 对文件重命名:
os.rename('test.txt', 'test.py')
# 删掉文件:
os.remove('test.py')
# 复制文件
from shutil import copyfile
copyfile('1.py', '11.py')   # 源文件 ==》 目标文件

把两个路径合成一个时,不要直接拼字符串。==》os.path.join() 函数,可以正确处理不同操作系统的路径分隔符。

同理,要拆分路径时==》os.path.split()函数,后一级别总是目录或文件名。

拆分扩展名——os.path.splitext() 函数

过滤文件

## 列出所有的.py 文件
print([x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1] == '.py'])

四、序列化

序列化:把变量从内存中变成可存储或传输的过程。在Python中称为 picking。

反序列化:把变量内容从序列化的对象重新读到内存里的过程。在Python中称为 unpicking。

1、pickle模块

把一个对象序列化并写入文件。

import pickle
d = dict(name = 'Bob', age = 20, score = 88)
pickle.dumps(d)
# b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x03\x00\x00\x00Bobq\x02X\x03\x00\x00\x00ageq\x03K\x14X\x05\x00\x00\x00scoreq\x04KXu.'

## 序列化到dump.txt文件中
f = open('dump.txt', 'wb')
pickle.dump(d, f)
f.close()

## 反序列化
f = open('dump.txt', 'rb')
d = pickle.load(f)
f.close()
print(d)

pickle.dumps() 方法:把任意对象序列化成一个bytes,然后就可以把这个 bytes 写入文件。
pickle.dump() 方法:直接把对象序列化后写入一个 file-like Object.

把对象从磁盘读取到内存时。
(1)内容=》bytes=》pickle.loads() 方法反序列化出对象
(2)直接用 pickle.load() 从一个file-like Object 中直接反序列化出对象。

注意:Python不同版本的Pickle可能不兼容,所以只能保存那些不重要的数据,不能成功反序列化也没关系。

2、JSON模块

序列化的标准化格式:JSON,且比XML快,可以在Web网页中读取。

JSON 与 Python的内置数据类型对应如下:

JSON类型Python类型
{}dict
[]list
“string”str
1234.56int 或 float
true/falseTrue/False
nullNone

dict 《==》dict

import json
d = dict(name = 'Bob', age = 20, score = 88)
print(json.dumps(d))

json_str = '{"age":20, "score":88, "name":"Bob"}'
print(json.loads(json_str))
(1)class 的序列化
import json
class Student(object):
    def __init__(self, name, age, score):
        self.name = name
        self.age = age
        self.score = score
## 序列化——default参数
s = Student('Bob', 20, 88)
# obj.__dict__:把任意 class 的实例变为 dict
print(json.dumps(s, default=lambda obj: obj.__dict__))

## 反序列化
def dict2student(d):
    return Student(d['name'], d['age'], d['score'])
json_str = '{"age":20, "score":88, "name":"Bob"}'
print(json.loads(json_str, object_hook=dict2student))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值