没有循环导入的Python类型提示
我正试图将我的大班分成两部分;好吧,基本上是进入“主”类和具有其他功能的mixin的,就像这样:
main.py
文件:
import mymixin.py
class Main(object, MyMixin):
def func1(self, xxx):
...
mymixin.py
文件:
class MyMixin(object):
def func2(self: Main, xxx): # <--- note the type hint
...
现在,尽管这很好,但类型提示MyMixin.func2
当然不起作用。我无法导入main.py
,因为会进行周期性导入,并且没有提示,我的编辑器(PyCharm)无法分辨出什么self
。
我正在使用Python 3.4,如果那里有解决方案,我愿意移至3.5。
有什么办法可以将我的班级分成两个文件并保留所有“连接”,以便我的IDE仍可以自动完成以及知道该类型的所有其他优点。
-
恐怕通常没有一种非常优雅的方式来处理导入周期。您的选择是重新设计代码以消除循环依赖性,或者如果不可行,请执行以下操作:
# some_file.py from typing import TYPE_CHECKING if TYPE_CHECKING: from main import Main class MyObject(object): def func2(self, some_param: 'Main'): ...
该
TYPE_CHECKING
常量始终False
在运行时运行,因此不会评估导入,但是mypy(和其他类型检查工具)将评估该块的内容。我们还需要将
Main
类型注释放入字符串中,以有效地向前声明它,因为该Main
符号在运行时不可用。如果您使用的是Python 3.7+,我们至少可以通过利用PEP
563来跳过必须提供显式字符串注释的情况:# some_file.py from __future__ import annotations from typing import TYPE_CHECKING if TYPE_CHECKING: from main import Main class MyObject(object): # Hooray, cleaner annotations! def func2(self, some_param: Main): ...
该
from __future__ import annotations
进口将使 所有 类型提示弦而跳过评估他们。这可以使我们的代码更符合人体工程学。综上所述,与mypy一起使用mixins可能会需要比您现在更多的结构。Mypy建议一种基本上就是
deceze
所描述的方法-
创建一个ABC,您的类Main
和MyMixin
类都继承。如果您最终需要做一些类似的事情以使Pycharm的检查器满意,我不会感到惊讶。