接续第一话的内容,事件循环在创建之后,又是如何运行协程任务以及异步IO任务的?
由asyncio.run
的代码可知,loop.run_until_complete
是运行协程的方法。其定义如下:
【Hard Python】【第二章-异步IO】1、asyncio事件循环的创建
python3中增加的重要特性之一即为asyncio
,其提供了异步编程的原语支持,从而能够让python在事件驱动、协程协同等方面的编程场景大杀四方。
事件循环EventLoop
是异步编程中的核心概念之一。python的异步IO,就从事件循环的实现开始讲起。
首先看一段示例代码:
1 | async def _test_run_main(): |
通过async def
定义的函数,其返回值是一个异步协程coroutine
。协程相当于是事件循环里的一个单位任务,通过asyncio.run
接口就可以将其运行起来。因此我们先来看asyncio.run
的实现:
【Hard Python】【第一章-多进程】3、Pool,多任务并行进程池
前面讲了进程创建与进程通信的内容,接下来讲一下多进程编程最能发挥的地方。对于同时运行多个同质任务来讲,采用multiprocessing.Pool
进程池去管理是最方便的。Pool
的用法如下:
1 | from multiprocessing import Pool, process |
打印出来的结果,可能是这样子的:
【Hard Python】【第一章-多进程】2、Pipe和Queue,进程间通信
第一话详细讲解了Process新进程是如何被创建的,接下来就来讲一下进程之间有什么通信的方法。
要在multiprocessing
中实现进程间通信,最直接的方法是采用Pipe
或者Queue
。其用法如下:
【Hard Python】【第一章-多进程】1、Process,新进程的诞生
在python中,如果要做多任务并行的编程,必须要掌握multiprocessing
库的相关运用。在python的multiprocessing官方文档中,已然详细给出了multiprocessing
库的相关用法。多进程编程其实还是有很多坑存在的,为了进一步探索python多进程的机制,提升对python多进程编程的理解,本篇文章会对多进程模块的实现进行一次详细的剖析。
多进程编程的第一话,首先来聊聊一个新的python子进程是如何诞生的。
首先我们需要了解这么一个事情,python创建的进程之间模块状态是相互隔离的。在多进程的场景下,代码中定义的各种变量,其值并不一定会共享。我们举个例子:
【Hard Python】前言
写完Medium Python之后,不知不觉就有开始继续写Hard Python的冲动。择日不如撞日,心动不如行动,2022年开篇,果断将Hard Python提上日程。
截至2021年底,python依旧是最热门的语言之一,随着3.10、3.11及后续版本的发布,python的runtime在功能及性能上都会有较大的提升。时至今日,提到技术应用最广泛的语言,除了python,还会有另外的吗?排除区块链、游戏、音视频里较为深度的领域,基本上各种技术业务场景,都会有python的影子。
可以说,python是编程界的一把瑞士军刀。如果我们能更加深入的了解python各个重点模块的技术原理,不仅对于我们理解这门语言以及编程语言相关技术有益处,并且以后我们在面对一些python的编程场景时也会更加得心应手。
在先前已经写过两个python系列,分别是Easy Python以及Medium Python。在Easy Python中,对python的各种基础概念以及实用场景介绍了相关案例;而在Medium Python中,通过源码分析的方式,剖析了python内部某些语言特性的实现,讲述了许多python相关的冷知识。这次Hard Python,还是回归本源,将会挑选一些python内部比较重点的基础模块进行深入剖析讲解,争取让每一位阅读本系列文章的同学对python这门语言有更加全新的理解。
话不多说,准备上菜!
目录
- 第一章:多线程
- 1、Process,新进程的诞生
- 2、Pipe和Queue,进程间通信
- 3、Pool,多任务并行进程池
- 第二章:异步IO
- 1、asyncio事件循环的创建
- 2、异步任务在事件循环中的执行
- 3、async/await的源码实现
- 第三章:GC
- 1、引用计数与内存释放机制
- 2、python的GC流程
- 第四章:日志
- 1、Logger与Manager的源码实现
- 2、日志消费者Handler的实现
- 第五章:字符串
- 1、unicode,py3的字符串实现
- 2、re,正则表达式源码详解
【Python随笔】如何提取python函数的接口定义信息
在某些python框架底层的开发需求中,需要通过一些类似反射的手段,提取函数接口的信息,从而对一系列函数接口进行管理。本篇文章就来粗浅谈一下,如何提取python函数的接口定义信息。
function对象的信息
首先我们拿一个函数来试试手:
1 | def myprinter(s: str, /, e: str = '\n', *, prefix: Any = '') -> Tuple[bool, str]: |
这个函数myprinter
采用了新的语法糖/
以及*
,/
的左边表示强制位置参数(positional-only arguments),*
的右边表示强制关键字参数(keyword-only arguments),而两者中间的参数在使用时以位置参数或者是关键字参数的形式表达都可以。
要提取这个函数的信息,我们首先要知道函数本身也是一种对象。因此,可以用到dir
函数,遍历这个对象的属性,从而提取所有属性的值。
通过dir
导出函数对象的属性与值,打印的结果如下:
【游戏开发】踩坑UE4的Python脚本插件
UE4以C++为基础,在游戏开发需求当中,官方推崇的是Blueprint可视化编程,而除此之外像UnLua、puerts等解决方案也提供了lua、ts等其它脚本语言的支持。至于python,UE4本身就有插件支持,叫做PythonScriptPlugin
,启用插件后,在编辑器里,可以输入python代码执行一系列命令。在最新的4.27版本中,python的版本是3.7.7。
回到正题,之所以这篇文章标题叫踩坑,是因为真的踩坑了——尝试用PythonScriptPlugin
来编写UE4的游戏逻辑,最终放弃。PythonScriptPlugin
适合做一些驱动编辑器的操作,或者是做一些静态资源检查相关的工作(其实这个插件真名就叫Python Editor Script Plugin
),如果用它来写游戏逻辑的话,很多必须的内容都难以支持。但不管怎么说,既然踩坑了还是要分享点东西出来,因此这篇文章先粗浅谈一下PythonScriptPlugin
的工作流。
【Medium Python】最终话:如何彻底理解with关键字的用法?
Medium Python终于来到了最终话。经历了前四话的撰写,笔者决定以第五话作为收尾,故这段时间一直在思考python里还有什么内容是我们常见但值得推敲且有应用意义的点。绞尽脑汁,最终得到了今天这个主题:with
关键字。
with
关键字的含义,是笔者接触python以来希望彻底搞懂的问题之一,也是一定会困惑大量玩python的同学的问题之一。相信每一个玩过python的同学都接触过with
语法,比如with open(xxx) as f
的文件操作,或者是with lock
这样的加解锁操作,这些东西每个python教程里都有。但是with
语法具体表示什么,具体能够翻译成怎样的简单语法,基本没啥人能够说的清楚,说的科学。即便在网上有许多文章在剖析这一点,提到了许多诸如“上下文管理(context manager
)”、“异常处理”、“__enter__
、__exit__
”之类的词汇,但是就正因为缺少些硬核的东西,比如源码分析,导致许多个文章的内容都很水,看了也不能完完全全的明白,实际写代码的时候也觉得难以彻底掌握。
因此,为了把这件事情说明白,本文决定继续源码分析的套路,让大伙儿彻底理解with
关键字是怎么一回事。老样子,一切的吹水都没有源码分析来的实在。看完这篇文章,其它关于with
的文章都可以统统无视了。
with代码测试
首先我们上一段测试代码:
【Medium Python】第四话:类属性和实例属性是怎样的关系?
前言
提到编程不得不提到面向对象,一个说烂了的话题,几十年来一直都有人在争论面向对象的好坏。从宏观角度来说,一个庞大的程序本质是对业务中实体集合以及其中的关系的模拟,虽然解决实体的关系问题,用面向过程、组合等方式去体现比较方便,但要解决实体概念的抽象,就需要面向对象的编程基础。因此,面向对象在编程中是非常重要的一部分思想,不能随随便便被否定或者忽略。
面向对象的灵魂在于对类(class)概念的剖析,而python中也有对类的支持,虽然不像其它静态语言有比较强的约束,但如果想将代码组织成面向对象式的话也是完全满足的。在平常python的交流以及面试的过程中,也会涉及到许多关于类的问题,比如最常见的就是阐述类与实例的关系。要理解类与实例的关系,从类属性和实例属性切入是为最直观的。因此,今天这篇文章就来讲讲python里类属性和实例属性的二三事。
在类和实例中访问属性
首先上一段测试代码: