不知道有没有类似项目,如果有的话请告诉我,
昨天发了个贴问了一下类型提示的循环导入问题,产生了一些发散式联想,能不能把现有的体系再升级一下做成一个自动检查项目,应该会挺有用的。
目前我司对于类型检查使用的是比较原始的方法,即手动增加装饰器,装饰器可以接管函数或方法的控制权,检查输入和输出是否符合标准。
而如果升级成框架的话,大概想了一下应该具有三种功能。
其一是类似直接引入式的用法,即可以嵌入一个通常程序中,对其中某个节点做检查,也是我们现在正在用的方法,这个技术上难度不大。
from 框架 import 类型检查
@类型检查
def func(a:int , b:str) -> None:
...
func()
其二是全局接管式,即通过修改 entrypoint 以命令行启动程序,替换 python3,对全局中的所有有类型标注的内容做检查。
root@vhost~# python3 main.py
替换成
root@vhost~# typecheck main.py
其三是接入 pytest,这个应该算是另外一个项目,比如做成 pytest 插件,暂不谈。
=============
这个项目的目的是在开发阶段,以及自动测试当中进行严格的类型约束,使程序在实际生产环境中关闭类型约束后仍然具有较高鲁棒性。它的好处是可以在最小侵入性的前提下(即保留 python 的设计哲学,pythoner 显然无意将 python 改变为一门静态类型语言,但可以通过掐头去尾的方式大幅提可靠性和降低维护难度)这是我个人的想法,我生产经验也不是特别丰富,如有错误各位指正。
大概思考了一下实现的困难,
其一是使用符合 PEP484 的类型提示规范,在目前的条件下,并且很可能未来版本中长期存在的一个问题是,对于包内循环导入,一些类型可能无法获得类实例,而只能获得包含类名的字符串。进行类型判断,从功能性角度讲理应可以向上递归,即如果定义输入类型为A 类
,那么输入 A 类和其子类都是可以接受的,这种情况下需要进行 isinstance 判断,类实例进行这种判断很容易实现,字符串实现起来比较困难。
其二是如何引入检查的问题。用户自行使用装饰器修改函数的话可以自然地引入检查,但如果要用类似命令行启动的方式,实际上在做的是检查程序接管控制权,hack 进入程序当中,将所有 runtime 运行的实例进行某种替换,以实现执行前和执行后的输入输出检查。我个人技术比较低微,不知道这种接管有没有可能实现,简单想了一下没什么好的办法,各位提提意见。
1
caviar 2021-01-27 20:23:42 +08:00
说实话没有完全看懂。
如果是静态检查的话,可以看下 https://github.com/python/mypy 如果是运行时检查的话,可以看下 https://typeguard.readthedocs.io/en/latest/userguide.html 有你说的用 decorator 的,也有用 profiler hook 的。 |
2
LeeReamond OP @caviar mypy 用过,另外还用过一个叫 pyright 的,那个不怎么样,mypy 的 ide 检查还不错,但是感觉我这个偏运行时?我研究一下你发这个 typeguard,还有 profiler hook 是啥,没听过这个词
|
3
LeeReamond OP 大概调研了一下,目前感觉一个可行的实现思路是这样,首先 hook 模式对我来说难以理解,暂时认为不可行,相反装饰器模式很简单,可以通过修改装饰器修改 metaclass,实现对普通函数,和类内所有函数的手动标注,这样注入之后程序在所有函数的入口和出口处都有了类型检查,在自动测试中自然也一样。
之后只需要在发布的时候删除装饰器就可以了,可以写一个非常简单的状态机搞定。 |
4
shniubobo 2021-01-28 09:49:43 +08:00 via Android
见过一个框架通过 monkey patch 标准库,在 io 操作时自动 yield,来实现并发的: https://nameko.readthedocs.io/en/stable/key_concepts.html#concurrency
借鉴这种方法,或许可以实现在完全不修改代码的情况下测试,而不需要测试时写上装饰器、发布时删掉。 |
5
frostming 2021-01-28 10:26:45 +08:00
|
6
LeeReamond OP @frostming mypy 的 pycharm 插件很好用,但是 runtime 我觉得很糟糕,经常卡死,异常又怪。不过刚才试了一下,之前没试过的,runtime 确实是支持 PEP563,这样说来也堪用了
|