仅仅为了类型提示而导入类,这种做法在Python中可行吗?

6
我正在尝试在Python 3.8中使用类型提示,但有一点卡住了。 例如:我主要在main.py中开发。我还有一个包含一些辅助函数和类的util.py类。但这些类也需要导入main.py中的类进行类型提示。现在,当我想在main.py中使用util.py中的函数时,我也需要导入它-但是我会因为循环导入而出错(这是正确的)。
有什么解决办法吗?
提前感谢!
3个回答

7

Sylvio的回答是正确的,但我想着重谈一下你标题中的仅仅为了输入

在Python中仅仅为了输入而导入类?

如果你导入一个类仅仅是为了解决一些输入方面的问题,你可以使用typing.TYPE_CHECKING常量来让该导入变成有条件的。

引用文档如下:

运行时或类型检查?

有时候代码必须被类型检查器(或其他静态分析工具)看到,但不应该被执行。 对于这种情况,typing模块定义了一个常量TYPE_CHECKING,它在类型检查(或其他静态分析)期间被认为是True,但在运行时为False。 例如:

import typing

if typing.TYPE_CHECKING:
    import expensive_mod

def a_func(arg: 'expensive_mod.SomeClass') -> None:
    a_var = arg  # type: expensive_mod.SomeClass
    ...

需要注意的是,类型注释必须用引号括起来,这使得它成为一个“前向引用”,以隐藏 expensive_mod 引用对解释器运行时的影响。在 # type 注释中不需要使用引号。

总之,在进行类型检查时,你可能完全不需要全部导入它,除非你正在进行类型检查


5
循环导入在Python中不会立即出错,只有在特定情况下使用它们才会出错。我相信你正在寻找前向引用
例子main.py:
import util

class SomeClass:
    pass

示例 util.py

import main

# We can't use main.SomeClass in the type signature because of the cycle,
# but we can forward reference it, which the type system understands.
def make_some_class() -> "main.SomeClass":
    return main.SomeClass()

-1

我认为防止这种情况的最好方法是将每个类都移动到自己的文件中,并在需要它们的地方导入它们。 在单个文件中声明多个类对于代码维护来说并不好,而且可能会使大型应用程序更难调试。

如果每个类都相互依赖,我不认为你可以避免循环导入的方式描述它


2
我不得不反对。"每个文件一个类"是非常Java式的思维方式,它是该语言的习惯用法,但在Python中,类和模块是不同的概念,没有理由自动将它们耦合在一起。 - Silvio Mayolo
Python不是Java。Silvio没有投反对票,这是可以理解的,因为他有一个“竞争”的答案,但这不是正确的方法。 - JL Peyret
1
作为新手,请原谅我点踩,但是重要的是不要用如此广泛的概括方式误导其他人,尤其是对于 Python 而言。欢迎加入。 - JL Peyret

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接