重新理解AsyncIO

1.概要 python下的协程 asyncio和gevent都是基于携程来进行并发操作的。协程也被称为微线程。 协程只是在单一的线程里进行切换不同的协程,因此无法使用多CPU能力,对于CPU密集型程序还是使用多进程比较好。 协程相比较进程和线程来说占用的内容更少,同样的线程切换更多的是靠操作系统来控制,而协程的执行则由我们自己控制。 并发与异步区分 并发原理:当其中一个协程遇到io等待时,将会切换到另一个协程继续运行。 并发与异步: 并发强调的是N人干同样的事,要保证不争抢 (lock,atomic,synchronize,volatile, cas) 异步强调的是1/N人干不同的事,不该等的别等 (thread pool, future, async,reactive) 看到并发的时候经常会看到异步,原因是一般所说的并发,指的是 【每个业务活动频率很低,但是有大量同时进行的业务活动】 这样用异步代码自己维护每个业务状态,而不劳驾系统通过线程/进程的方式维护每个业务状态的方式,能把这个场景实现得性能更好,内存占用更少。 如果业务活动频率又高,又同时大量进行,那就超出异步的解决范围了。那是分布式处理的范畴。 需要协程原因 1.多线程运行过程容易被打断,有可能出现race condition的情况 2.线程切换本身存在定的消耗,若/0操作非常heavy,多线程很有可能满足不了高效率、高质量的需求。 sync和async的概念区分 sync即同步,指操作个接个地执行,下一个操作必须等上一个操作完成后才能执行。 asynd即异步,指不同的操作可以交替执行,如果其中某个操作被block了,程序并不会等待,而是会找出可执行的操作继续执行。 Asyncio的缺陷 在实际工作中,要想用好Asyncio,必须得有相应的python库支持。在之前的多线程例子中,我们用到的是requests库,而在这里使用的却是aiohttp库,原因就在于requests库与Asyncio不兼容,但aiohttp库兼容。但是兼容问题会随着版本的问题逐步减少。 此外,使用Asyncio使得我们在任务调度方面有更大的自主权,写代码时就得更加注意,否则容易出现错误。 比如,如果你需要await一系列的操作,就得使用asyncio.gather();如果只是单个的future,则用asyncio.wait()就可以了。那么,对于你的future,是想让它run_until_complete()还是run_forever()呢?此类问题都是在面对具体问题时需要去考虑的。 那么使用asyncio时 如何搭配第三方库 首先,最简单的办法就是搜一下这个库的源码里是否出现了 asyncio 或 async def 的字样,如果没有出现则几乎可以证明这个库没有对 asyncio 有做特别的支持。为了彻底证实,还应仔细阅读其代码,查看关键 I/O 部分是如何实现的。 对于暂不支持 asyncio 的第三方库,可以按以下步骤依次排查: 1. 确认其 I/O 时间比例是否占到大部分。比如用 SQLAlchemy 时,如果能基本上确保数据库操作都是瞬时的,那么[理论上](http://techspot.zzzeek.org/2015/02/15/asynchronous-python-and-databases/)是可以任由其阻塞主线程的。而对于明显 I/O 占大多数时间且时间不可预测的,比如 requests,就不能让其成为性能瓶颈; 2. 确认其 I/O 的并发能力是否会成为瓶颈。比如说还是用到了 requests,但平均下来每 10 分钟才会发一个请求,其他时间主要都用在数据库计算上了,那么完全可以把 requests [放到线程池里](https://docs.python.org/3/library/asyncio-eventloop.html#executor)去做; 3. 确实需要异步了,首先查找其 asyncio 的扩展,有时会有单独的库做 asyncio 支持,比如 peewee_async; 4....

重新理解AsyncIO

Python终端Debug调试:Pdb

使用Pdb模块:breakpoint()方法 程序当中,至少要有一个breakpoint() 在你需要的打断点的位置,加上: breakpoint() 查看调用栈:w | where 显示的是从上到下的 路径/文件.py(括号里是行号) (Pdb) w d:\administrator\projects\pdb_test.py(12)<module>() -> func_obj = func1() > d:\administrator\projects\pdb_test.py(4)func1() -> def inner(value): ''' > 仅右箭头:表示当前frame ''' 切换帧(调整当前帧frame):u、d u | up d | down (Pdb) u > d:\administrator\projects\pdb_test.py(12)<module>() -> func_obj = func1() (Pdb) w > d:\administrator\projects\pdb_test.py(12)<module>() -> func_obj = func1() d:\administrator\projects\pdb_test.py(4)func1() -> def inner(value): 查看断点附近代码:l、ll l | lst:默认显示附近11行 l . :回到当前行 ll | longlst:查看当前函数全部代码 (Pdb) l 1 def func1(): 2 data = [] 3 breakpoint() 4 -> def inner(value): 5 data....

Python终端Debug调试:Pdb

如何打包发布Python包至私有仓库

如何打包发布Python包至私有仓库 Python 中的库(package)可以分为标准库和三方库,标注库是在安装Python后,默认安装的库,如math,json等。其余的库可以称之为三方库,需要在使用前单独安装。我们经常使用到 pip install <package> 这个命令就是用于安装三方库的。这里我们只需要指定包名即可非常简单的实现三方库的安装。那么包存储在什么地方,我们是从何处下载安装的呢? PyPi​ Pip install 命令支持四种来源的安装: PyPI (and other indexes) VCS 本地项目目录 本地/远程 的 archives Python 安装包教程:https://packaging.python.org/tutorials/installing-packages/#installing-packages 首先,我们介绍下什么是PyPi。PyPi 是The Python Package Index 的缩写,是Python社区用来开发和共享软件的一种软件仓库。 一般如果在使用 pip 安装、搜索第三方Python库的时候,默认使用 Pypi源,若是希望使用其余(私有)的源,可以通过 -i/--index-url指定。 -i, --index-url <url> Base URL of the Python Package Index (default https://pypi.org/simple). This should point to a repository compliant with PEP 503 (the simple repository API) or a local directory laid out in the same format. 如经常使用 清华Pypi镜像 加速某些包下载时经常使用如下方式...

如何打包发布Python包至私有仓库

Alembic数据库迁移工具使用

背景 在很多时候,在我们设计好模型之后,又需要进行一定的改变和更新数据操作;最直接的方式就是删除原来的旧表,但我们之前的数据也会删除;究其原因是我们不能精确记住每个修改和对应DDL,这时候就需要数据库迁移框架了。 对于Django ,框架内部就集成了数据库迁移模块,我们可以很方便使用 回顾Django迁移命令: 基本语法: python manage.py xx [app_name] xx如下: migrate,负责应用和撤销迁移。 makemigrations,基于模型的修改创建迁移。 sqlmigrate,展示迁移使用的 SQL 语句。 showmigrations,列出项目的迁移和迁移的状态。 Django迁移过程分为3步走: 1:修改models数据模型 2:生成迁移文件(在migrations/文件夹下)python manage.py makemigrations 3:向数据库执行迁移操作:python manage.py migrate 总结,迁移数据库的主要思路: 1:修改数据模型 2:生成新迁移文件 3:执行迁移 那么在Flask + SQLAlchemy下,如何选择数据库管理迁移工具? Alembic介绍 Alembic是Sqlalchemy的作者就已经实现的一个数据库版本化管理工具: Alembic来帮助我们实现数据库的迁移,数据库迁移工具可以在不破坏数据的情况下更新数据库表的结构。蒸馏器(Alembic)是炼金术士最重要的工具,要学习SQL炼金术(SQLAlchemy),当然要掌握蒸馏器的使用。 Alembic 是一个处理数据库更改的工具,它利用 SQLAlchemy 来实现形成迁移。因为 SQLAlchemy 只会在我们使用时根据 metadata create_all 方法来创建缺少的表 ,它不会根据我们对代码的修改而更新数据库表中的列。它也不会自动帮助我们删除表。 Alembic 提供了一种更新 / 删除表,更改列名和添加新约束的方法。因为 Alembic 使用 SQLAlchemy 执行迁移,它们可用于各种后端数据库。 快速上手 # 安装alembic pip install alembic # 初次使用时,需要初始化,创建迁移环境和 alembic.ini 文件、env.py文件 alembic init migrations # 修改alembic.ini配置,改变 sqlalchemy.url 值,配置数据库连接。 sqlalchemy....

Alembic数据库迁移工具使用