我们知道,在写Python时,使用IDE的自动补全功能,可以大大提高代码的开发效率。使用类型标注功能,可以让IDE知道应该怎么做自动补全。
当我们没有类型标注时,IDE并不知道函数的某个参数是什么东西,没有办法做补全,如下图所示。
但当我们把类型标注加上以后,IDE就能正常补全了,如下图所示:
这样做,需要从另一个文件中,把这个参数对应的类导入到当前文件里面,然后把类作为类型填写到函数参数后面。咋看起来没有什么问题,并且我,还有很多看文章的同学,应该经常这样写类型标注的代码,从而提高代码的开发效率。
但如果你的项目规模大起来以后,你就会遇到几个比较麻烦的问题:
- 导入链过长:例如上面截图中的代码,我从
model.py
中导入了Detail
这个类。如果我在model.py
文件的开头,还有from aaa import bbb
,而在aaa.py
文件开头,又有from ccc import ddd
;在ccc.py
开头,又有from xxx import yyy
……这个导入链条就会变得很长。虽然Python对模块导入已经做了缓存,多次执行from xxx import yyy
时,只有第一次会生效,后面都是读取缓存,但读取缓存也会消耗一些时间。 - 循环依赖:一般情况下,你的代码能够正常运行,那么应该是不会存在循环依赖的。否则肯定报错了。但现在你在一个原来的依赖链条之外的文件中,为了做类型标注,导入了一个已有的文件。此时有可能就会引入循环依赖。特别是当代码规模大起来以后,如果一开始没有设计好代码结构,稍不注意就会出现循环依赖。
如果你引入一个类,仅仅是为了做类型标注,那么这个问题实际上非常好解决。在Python的typing模块里面,有一个常量,叫做TYPE_CHECKING
,它就是为了解决这个问题而设计的。在你使用python xxx.py
来启动代码时,TYPE_CHECKING
的值是False
。但当IDE的类型检查或者Mypy
这种静态类型检查工具运行时,TYPE_CHECKING
的值是True
。
因此,我们可以使用下面这段代码,来提高代码的运行效率,同时规避循环依赖的问题:
1 | from typing import TYPE_CHECKING |
注意,在函数参数的类型标注里面,类YYY
需要以字符串的形式写出。如下图所示:
使用这种方法,在写代码时,IDE能够正确的做自动补全。在Mypy
做静态类型检查时,也能过正常通过检查。但当代码实际运行时,会自动忽略这个导入的类,从而避免对代码的运行效率造成影响。