前言
学common lisp(以下除非特殊需要说明的都简称lisp)以及用emacs的人都有一个体会 - lisp无所不能,
可以使用lisp修改lisp的行为. 什么意思呢?
我来举个例子. 我希望重置+
的行为为实际意义的减法-
. 看起来这是语言不可能完成的任务, 对lisp来说很简洁(我使用sbcl):
1 |
|
是不是很神奇?
那么对于python这种高级语言能不能做到呢? 答案是肯定的. 我们马上就来实现它
1 |
|
我想大家开始明白AST有多大能量了吧?
AST的故事
AST中文叫做抽象语法树,
也就是分析当前版本的python代码的语法, 用一种树的结构解析出来
.
这个模块提供给我们一个在编译代码之前, 用python语言本身去修改.
它的作者是Armin Ronacher.
如果你听过或者觉得似曾相识, 对. 他就是mitsuhiko - flask的作者.
也是pocoo的leader之一(另外一个是看起来不知名的birkenfeld - 对我来说他很有名).
那么AST有什么意义呢? 但是有绝大多数人其实不了解也用不到这个模块, 为什么呢?
- 出现需要对代码默认行为做更改的场景很少
- 它主要用来做静态文件的检查, 比如pylint, pychecker,以及写flake8插件. 而我们平时的写代码都是在运行不需要进行预先的语法检查之类, 那么实际接触它就很难得了.
一些文章的索引
为了对本文有更深的理解可以看看以下文章
[AST 模块:用 Python 修改 Python 代码](http://pycoders-weekly-
chinese.readthedocs.org/en/latest/issue3/static-modification-of-python-with-
python-the-ast-module.html#cpython)这里对流程说的很好了. 可以直接读一下
模块代码也写得非常精炼, 可能不直接让你明白, 那么这时候可以看看
Abstract Syntax Trees,
这个时候我再强调一下作者吧, takluyver是ipython的核心开发成员, 他也参与了很多我们常用的开源项目, 比如pexpect和pandas
上面的2篇文章写了很多, 既有理解, 也有一些初级的用法.我个人用它的例子
最近做的slack-alert. 先说它和AST的关系: - 我没有使用注册或者import的方式,而是直接去遍历文件, 找到符合我要求的函数当做一个任务需要执行的任务
- 任务就要设置间隔, 那么会加某种格式的装饰器, 装饰器的参数就是间隔类型, 比如
@deco(seconds=10)
表示没十秒跑一次的意思 - 我这样就可以放心的写plugin就好了, 我只关注任务本身的逻辑. 而这个装饰器(类似上面说的@deco), 它其实是不存在
- 这个特殊格式的装饰器本身不存在没有关系, 因为我不会直接运行代码, 我只是把代码通过AST的处理, 解析出我要的任务和任务的执行间隔. 再去编译代码.
上代码:
1 |
|
其实看起来不能完成的事情, 就是这么简单.
版权声明:本文由 董伟明 原创,未经作者授权禁止任何微信公众号和向掘金(juejin.im)转载,技术博客转载采用 保留署名-非商业性使用-禁止演绎 4.0-国际许可协议
python