背景
了解过编程的人应该对函数重写 ( override ) 不陌生,但其实,这个普适的方法并不适用于所有的应用场景。举个简单的例子,当多个项目代码贡献方都想参与同一程序的修改时,频繁的函数重写会使代码变得异常混乱,让整个项目变得难以维护。
那么,有没有更优雅的方法能够兼顾代码的扩展性与稳定性呢?
有的,pytest ( python 单元测试框架 ) 的作者就意识到了这个问题。在其源码中,可以发现许多经过 @pytest.hookimpl 关键字装饰的函数,这代表这个函数是一个插件的实现,其作用是通过用插件调用的形式来替代函数重写。。
pytest 部分源码:
@pytest.hookimpl(hookwrapper=True)
def pytest_load_initial_conftests(early_config: Config):
ns = early_config.known_args_namespace
if ns.capture == "fd":
_py36_windowsconsoleio_workaround(sys.stdout)
_colorama_workaround()
_readline_workaround()
pluginmanager = early_config.pluginmanager
capman = CaptureManager(ns.capture)
pluginmanager.register(capman, "capturemanager")
# make sure that capturemanager is properly reset at final shutdown
early_config.add_cleanup(capman.stop_global_capturing)
# finally trigger conftest loading but while capturing (issue93)
capman.start_global_capturing()
outcome = yield
capman.suspend_global_capture()
if outcome.excinfo is not None:
out, err = capman.read_global_capture()
sys.stdout.write(out)
sys.stderr.write(err)
早前在 pytest 中这只是一个插件工具库,而随着这个库的日益发展, 作者把它从 pytest 中分离了出来,并将其命名为了 pluggy。
赏金任务

今天的学习内容是要用 pluggy 把当前项目里的类和函数转变为插件,来代替函数重写。
预估赏金:约 1500 人民币。
任务拆解
一般在开始工作前需要将任务进行拆解,划分成数个小任务。而这个任务,基本可以划分为以下三步:
- 1.理解插件的概念与设计;
- 2.学习 pluggy 的使用;
- 3.将目标类转化为插件。
于是在一顿废寝忘食的编码后......

任务回顾
任务实际耗时在 15 个小时左右。
任务进行过程中,发现写代码并不是最难的,难的是如何将当前项目的代码结构插件化。过去的固化编码思维让我很难短时间想明白并作出实践。大概在做了1、2次代码重构,推翻了1次原有代码后,才终于完成了这个任务。
有时候代码思维比代码更加重要。十分感谢这次学习让我深刻理解了编程的另一种可能性。
期待下一个学习任务,也欢迎想要一起学习的小伙伴多多交流。