没有循环导入的Python类型提示

发布于 2021-01-29 19:21:33

我正试图将我的大班分成两部分;好吧,基本上是进入“主”类和具有其他功能的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仍可以自动完成以及知道该类型的所有其他优点。

关注者
0
被浏览
52
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    恐怕通常没有一种非常优雅的方式来处理导入周期。您的选择是重新设计代码以消除循环依赖性,或者如果不可行,请执行以下操作:

    # 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,您的类MainMyMixin类都继承。如果您最终需要做一些类似的事情以使Pycharm的检查器满意,我不会感到惊讶。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看