当前位置: 首页 > 面试题库 >

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

荀裕
2023-03-14
问题内容

我正试图将我的大班分成两部分;好吧,基本上是进入“主”类和具有其他功能的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,您的类MainMyMixin类都继承。如果您最终需要做一些类似的事情以使Pycharm的检查器满意,我不会感到惊讶。



 类似资料:
  • 我试图把我庞大的班级一分为二;好的,基本上分为“main”类和带有附加函数的mixin,如下所示: 文件: 文件: 现在,虽然这很好,但是

  • 我有Python类,它们有彼此作为属性的实例 如果这些类是在同一个文件中定义的,那么这很好,但是在我的例子中,它们都非常大,我希望将它们移动到不同的文件中。但是,如果我这样做,我必须将导入和导入,这将导致循环导入错误。有人知道我可以使用哪种模式将和放在不同的文件中,保持类型暗示,并遇到循环导入错误吗?

  • 问题内容: 如果两个模块相互导入会怎样? 为了概括这个问题,Python中的循环导入又如何呢? 问题答案: 导入确实非常简单。只要记住以下几点: 和是可执行语句。它们在运行的程序到达该行时执行。 如果模块不在中,则导入将在中创建新的模块条目,然后在模块中执行代码。在执行完成之前,它不会将控制权返回给调用模块。 如果中确实存在一个模块,则无论导入是否完成执行,导入都会简单地返回该模块。这就是循环导入

  • 问题内容: 所以我得到这个错误 并且你可以看到我进一步使用了相同的import语句,并且可以正常工作吗?关于循环导入是否有一些不成文的规定?如何在调用堆栈的更下方使用同一类? 问题答案: 我认为jpmc26的答案虽然绝非错误,但在循环进口上却过于严格。如果正确设置它们,它们可以正常工作。 最简单的方法是使用语法,而不是。前者几乎总是可以工作,即使包括在内也能使我们重新获得利益。后者只有在中已经定义

  • 问题内容: 假设我具有以下目录结构: 在软件包的中,将导入软件包。但是进口。 程序失败,表示尝试导入b时不存在。(它实际上不存在,因为我们正在导入它。)`c_file.pya.b.d `如何解决这个问题? 问题答案: 如果a取决于c,而c取决于a,那么它们实际上不是同一单位吗? 您应该真正检查一下为什么将a和c拆分为两个包,因为您应该将一些代码拆分为另一个包(以使它们都依赖于该新包,而不是彼此依赖

  • 问题内容: 我真的没有得到这个,所以如果有人可以解释它是如何工作的,我将非常感激。我有两个应用程序,“帐户”和“主题” …这是我的设置列表: 在帐户中,我正在尝试执行以下操作: 在我的主题模型中: Django踢出以下错误: 这是某种循环进口问题吗?我尝试使用一个懒惰的引用,但这似乎也不起作用! 问题答案: 删除的导入,并将模型名称用作字符串。