IO
IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。CPU和内存的速度远远高于外设的速度,所以,在IO编程中,就存在速度严重不匹配的问题。
磁盘IO:读写磁盘文件
f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')
# r -- 读
# w -- 写
# b -- 二进制,图片、视频等,rb 、 wb
# a -- 追加, wa
# + -- 可读可写,r+ 、w+、a+
# encoding="" 对应文件的编码方式
内存IO:读写内存数据
from io import StringIO # 内存读写str
from io import BytesIO # 内存读写bytes
s = StringIO()
s.write('hello')
s.readline()
b = BytesIO()
b.write('中文'.encode('utf-8'))
b.getvalue()
操作文件和目录IO:
* os模块:与操作系统交互*
* sys模块:与解释器交互*
import os
os.name # 操作系统类型,posix,说明系统是Linux、Unix或Mac OS X,如果是nt,就是Windows系统
os.environ # 操作系统的环境变量
# 查看当前目录的绝对路径:
>>> os.path.abspath('.')
'/Users/michael'
os.path.isdir('/Users/michael/testdir')
True
os.listdir('.')
['.lein', '.local', '.m2', '.npm', '.ssh', '.Trash', '.vim', 'Applications', 'Desktop', ...]
# 在某个目录下创建一个新目录,首先把新目录的完整路径表示出来:
>>> 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')
序列化IO:
变量从内存中变成可存储或传输的过程称之为序列化,pickle模块,python字典对象转二进制
把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling
DRF框架中的序列化:将程序中的一个数据结构类型转换为其他格式,模型类对象转json
>>> import pickle
>>> d = dict(name='Bob', age=20, score=88)
>>> pickle.dumps(d) # 字典对象,转bytes,序列化
b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x14X\x05\x00\x00\x00scoreq\x02KXX\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Bobq\x04u.'
>>> f = open('dump.txt', 'rb')
>>> d = pickle.load(f) # bytes数据转dict对象d,反序列化
>>> f.close()
>>> d
{'age': 20, 'score': 88, 'name': 'Bob'}
DRF中,将前端POST传来的json数据,反序列化为模型类对象,存入数据库。或者将模型类对象序列化为json,在前端GET时,返回。
同步和异步的概念描述的是用户线程与内核的交互方式
同步IO:是指用户线程发起IO请求后需要等待(阻塞)或者轮询内核(非阻塞)IO操作完成后才能继续执行;
异步IO:是指用户线程发起IO请求后仍继续执行,当内核IO操作完成后会通知用户线程(事件冒泡),或者调用用户线程注册的回调函数。
异步IO模型需要一个消息循环,消息循环中,程序只发出IO请求,主线程不处理,IO完成之后,消息通知,主线程再来进行处理。主线程只在不同已完成IO的代码上处理
1、协程:
线程数量越多,协程的性能优势就越明显。
共享资源不加锁,只需要判断状态就好
Python对协程的支持是通过generator实现的。yield(回调)
2、asyncio模块:
import asyncio
@asyncio.coroutine
def hello():
print("Hello world!")
# 异步调用asyncio.sleep(1):
r = yield from asyncio.sleep(1)
print("Hello again!")
# 获取EventLoop:
loop = asyncio.get_event_loop()
# 执行coroutine
loop.run_until_complete(hello())
loop.close()
*3、async/await(Python3新功能):
把@asyncio.coroutine替换为async;
把yield from替换为await。
4、aiohttp(基于asyncio实现的HTTP框架):
pip install aiohttp
import asyncio
from aiohttp import web
async def index(request):
await asyncio.sleep(0.5)
return web.Response(body=b'<h1>Index</h1>')
async def hello(request):
await asyncio.sleep(0.5)
text = '<h1>hello, %s!</h1>' % request.match_info['name']
return web.Response(body=text.encode('utf-8'))
async def init(loop):
app = web.Application(loop=loop)
app.router.add_route('GET', '/', index)
app.router.add_route('GET', '/hello/{name}', hello)
srv = await loop.create_server(app.make_handler(), '127.0.0.1', 8000)
print('Server started at http://127.0.0.1:8000...')
return srv
loop = asyncio.get_event_loop()
loop.run_until_complete(init(loop))
loop.run_forever()
并发:同时发生,发生的是事情,多件事情,指的是单核下的多线程、多进程等程序
并行:同时行走,行走的是人,多个人,指的是多核下不在同一核心运行的多线程、多进程等程序
**高并发:**大量的用户访问、大量的的并发请求
应对:
1、HTML静态化
2、图片服务器分离
3、数据库集群和库表散列
M-S(主-从)方式进行同步复制,将查询和操作和分别在不同的服务器上进行操作
4、缓存
5、镜像
6、负载均衡
**高可用:**系统正常运行时间与总运行时间的百分比,如99.999%