15 wrapt 模块使用
GrahamDumpleton wrapt blog 的翻译部分到此就结束。很可惜的是作者并没有把猴子补丁部分写完,查阅了 wrapt 的官方文档,上面只介绍了 wrapt 的装饰器,代理对象以及 synchronized 同步装饰器,也没有介绍猴子补丁相关内容。不过已经介绍的内容足够用了,接下来我想结合 wrapt 的文档介绍一下 wrapt 模块的使用,算是整个博客的总结。
GrahamDumpleton wrapt blog 的翻译部分到此就结束。很可惜的是作者并没有把猴子补丁部分写完,查阅了 wrapt 的官方文档,上面只介绍了 wrapt 的装饰器,代理对象以及 synchronized 同步装饰器,也没有介绍猴子补丁相关内容。不过已经介绍的内容足够用了,接下来我想结合 wrapt 的文档介绍一下 wrapt 模块的使用,算是整个博客的总结。
前面我们已经决绝了猴子补丁的导入次序问题,但是这个解决方案有个前提,就是我们必需能修改应用程序代码,以在程序的最开始执行我们的注册函数。本节我们的目的是找到另一种解决方案取消这个限制。
本节我们就来解决如何在 Python 中打补丁的问题。
在第 11 篇博客中,我们提到了应用猴子补丁时可能存在的问题。具体地说,如果需要被打补丁的模块已经被导入并被其他代码使用,那么它可能已经在自己的名称空间中创建了一个被打补丁的目标函数的本地引用。因此,尽管猴子补丁可以正常工作,但是仍然无法覆盖这种原始函数已经导入,并过通过本地引用直接访问原始函数的情况。
前面我们说道过 Python 中使用猴子补丁典型情景之一就是使用模拟库来帮助执行单元测试,本节我们先把补丁和模块导入的相对次序问题放一放,先来看看如何使用 wrapt 模块辅助单元测试。
在之前 10 篇博客中,我们几乎完整的讨论了装饰器的实现。现在我们将焦点从装饰器转移到猴子补丁上来。
通常在Python中永远不应该做的事情之一就是编写猴子补丁。但有些人认为这是一种有用的必需品,你可能无法避免修补第三方代码中的错误。其他人则可能会争辩说,现在有这么多的软件是开源的,所以您应该简单地向上游包维护人员提交一个补丁。
在上一篇文章中,我们对作为函数闭包实现的装饰器与前文描述的通用装饰器进行了性能比较。本节我们继续我们的性能测试,看看装饰一个类方法时,不同实现方式的性能表现。