上个月关于 Python 的 Decorator 写过一篇 Python 多层 decorator 内获取原始函数参数字典,后来熊提醒这种比较通用的东西应该都会有现成的库,搜了下果然有 个库就叫 Decorator
相关的项目地址在
- https://pypi.org/project/decorator/ PyPi 仓库
- https://github.com/micheles/decorator 项目主页
- http://decorator.readthedocs.io/en/latest/ 文档入口
看了下源码,他比之前我的做法更进一步,直接把要修饰的原方法的名字和参数,都扫代码解析出来,再到一个解析器的临时文件里原样写一个新的方法,并把相关需要复制的参数属性等都直接复制给这个新方法,这个新方法再调修饰方法,就可以更完美的实现对外界透明
例如这样的代码
def foo(x, y=2, *args, **kw): print(x) def dec(func): def wrapper(*args, **kw): print("called %s with %s, %s" % (func.__name__, args, kw)) return func(*args, **kw) return wrapper foo = dec(foo)
在经过了 @decorator
后会变成
_func = foo _caller = wrapper foo = def foo(x, y=2, *args, **kw): return _caller(_func)(x, y, *args, **kw)
只有一些涉及到 func_code 内存地址的地方才可以发现不一样
果然还是有库用库,绝大部分情况人家还是实现得更好,就是原理能不能看懂了。自己折腾的好处是正向推过去,坑和原理都比较了解,而反向看别人的代码,有很多奇妙的地方先想明白为什么要考虑这个情况,以及这个情况为什么要这样处理,都需要花很久
最后小吐槽一下,在 decorator 库里,如果是 py3,replace('return', 'return await')
真的没问题?如果有人逗比写了个 returnVal = xxx
不就崩了