python 指南(10)IO流

文件读写

一、IO简介

  • IO的概念
  • 流的概念
  • 同步和异步IO
  • 异步IO的实现:回调和轮询
  • IO编程接口

二、文件读写

1、读文件

  • python读取文件的最佳实践:使用 with 语句即便出现IO错误,文件资源还是能够被正确关闭
with open('/path/to/file', 'r') as f:
    print(f.read())
  • 如果文件很小,read()一次性读取最方便;如果不能确定文件大小,反复调用read(size)比较保险;如果是配置文件,调用readlines()最方便
for line in f.readlines():
    print(line.strip())
file-like Object
  • 类文件对象就是含有read方法的对象
  • 除了file外,还可以是内存的字节流,网络流,自定义流等等
二进制文件
  • 要读取二进制文件,比如图片、视频等等,用rb模式打开文件即可
字符编码
  • 指定编码
f = open('/Users/michael/gbk.txt', 'r', encoding='gbk')
  • 忽略非法编码字符
f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')

2、写文件

  • 写文件最后一定要 close 才能保证数据完全从内存存到磁盘,可以给 open 指定encoding参数转换成指定编码
  • w 的模式打开文件资源进行文件写入的话如果存在同名文件会被直接覆盖,以 a 模式打开才是以追加的模式写文件
with open('/Users/michael/test.txt', 'w') as f:
    f.write('Hello, world!')

StringIO和BytesIO

一、StringIO

  • StringIO是在内存中读写str
from io import StringIO

f = StringIO('Hello!\nHi!\nGoodbye!')
print(f.getvalue())
f.write("what is your name")
print(f.getvalue())
while True:
    s = f.readline()
    if s == '':
        break
    print(s.strip())

二、BytesIO

  • StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO,BytesIO实现了在内存中读写bytes
from io import BytesIO

f = BytesIO()
f.write('中文'.encode('utf-8'))
print(f.getvalue().decode('utf-8'))

f1 = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
print(f1.read().decode('utf-8'))

操作文件目录

  • Python内置的os模块也可以直接调用操作系统提供的操作文件和目录的接口函数
  • os模块的某些函数是跟操作系统相关的,比如uname函数win没有提供,linux上就有
  • 在操作系统中定义的环境变量,全部保存在os.environ这个变量中
  • 要获取某个环境变量的值,可以调用os.environ.get('key')

一、操作文件和目录

  • 操作系统的目录和文件操作的函数有的在os模块中,有的在os.path模块中

1、目录操作

目录的创建删除查看
import os
# 查看当前目录的绝对路径:
print(os.path.abspath('.'))
# 创建一个目录:
os.mkdir('d:\\testdir')
# 删掉一个目录:
os.rmdir('d:\\testdir')
目录字符串的操作
  • 路径字符串的拆分和合并不要直接通过+等方法操作字符串,使用os.path提供的函数可以屏蔽操作系统分隔符的差异
  • 这些合并、拆分路径的函数并不要求目录和文件要真实存在,它们只对字符串进行操作
import os
print(os.path.join('/Users/michael', 'testdir'))
# 分离文件和目录
print(os.path.split('/Users/michael/testdir/file.txt'))
# 分离出文件的扩展名
print(os.path.splitext('/path/to/file.txt'))

2、文件操作

  • 文件的新建和写入前面已经提过,这里主要是文件的重命名、复制和删除
os.rename('1.text','1-1.text')
os.remove('2.text')
import shutil
shutil.copyfile('1-1.text','2.text')

3、文件目录过滤

  • 列出当前目录下的所有目录
print([x for x in os.listdir('.') if os.path.isdir(x)])
  • 列出所有的.py文件
print([x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1] == '.py'])

序列化

一、python序列化

1、序列化和反序列化

  • 把变量从内存中变成可存储或传输的过程称之为序列化
  • 把变量内容从序列化的对象重新读到内存里称之为反序列化

2、python序列化实现(pickle)

  • Python提供了pickle模块来实现序列化,pickle序列化的局限性在于只能用于python,甚至不同版本的python都不一定兼容更别说其他的语言了
import pickle

d = {'a': 1, 'b': 124, 'c': 35556}
f = pickle.dumps(d)
print(f)
d1 = pickle.loads(f)
print(d1)

# 序列化写到文件
with open('dump.txt', 'wb') as f1:
    pickle.dump(d, f1)

with open('dump.txt', 'rb') as f2:
    print(pickle.load(f2))

二、标准序列化(json)

1、字典序列化

  • 这也是最基本的使用,字典和json可以无缝转换
import json

d = {'a': 1, 'b': 124, 'c': 35556}
d1 = json.dumps(d)
print(d1)
print(type(d1))
d2 = json.loads(d1)
print(d2)
print(type(d2))

在这里插入图片描述

2、类对象序列化

  • 普通的类是不支持直接的序列化和反序列化的,需要自己定义一转换的函数,转换函数的作用就是将类或者是序列化的对象转换为字典,字典和json就是无缝转换了
class Student(object):
    def __init__(self, name, age, score):
        self.name = name
        self.age = age
        self.score = score

    def __str__(self):
        return 'Student name=%s age=%s score=%s' % (self.name, self.age, self.score)


def stu2dict(stu):
    return {
        'name': stu.name,
        'age': stu.age,
        'score': stu.score,
    }


import json

stu1 = Student('allen', 24, 99)
jtu1 = json.dumps(stu1, default=stu2dict)
print(jtu1,type(jtu1))
stu2 = json.loads(jtu1, object_hook=lambda dic: Student(dic['name'], dic['age'], dic['score'], ))
print(stu2, type(stu2))

在这里插入图片描述

总结
  • Python语言特定的序列化模块是pickle,但如果要把序列化搞得更通用、更符合Web标准,就可以使用json模块
  • json模块的dumps()和loads()函数是定义得非常好的接口的典范。当我们使用时,只需要传入一个必须的参数。但是,当默认的序列化或反序列机制不满足我们的要求时,我们又可以传入更多的参数来定制序列化或反序列化的规则,既做到了接口简单易用,又做到了充分的扩展性和灵活性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值