Python 中避免循环导入的小技巧

在 Python 编程中,循环导入是一个常见的问题,它可能导致程序在运行时出现错误。循环导入指的是两个或多个模块互相导入对方,形成导入循环。这种情况下,模块可能无法被正确加载,从而导致运行时错误。Python 的类型提示功能提供了一种解决循环导入问题的方法,即使用 TYPE_CHECKING 常量。这个常量在类型检查阶段为 True,在运行时为 False。通过在模块中使用 if TYPE_CHECKING: 语句,可以避免循环导入的问题。

下面是一个使用 TYPE_CHECKING 避免循环导入的例子。假设我们有两个模块:workspace.pyagent.py。在 workspace.py 中,我们定义了一个 WorkspaceRead 类,它需要使用 agent.py 中定义的 AgentRead 类型。同样,在 agent.py 中,我们定义了一个 AgentRead 类,它需要使用 workspace.py 中定义的 WorkspaceRead 类型。为了避免循环导入,我们可以在两个模块中使用 if TYPE_CHECKING: 语句来导入对方模块的类型。

# workspace.py
from . import DTOBase
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from .agent import AgentRead

class WorkspaceBase(DTOBase):
    name: str
    directory: str

class WorkspaceRead(WorkspaceBase):
    id: int
    usable_agents: list[AgentRead] = 

class WorkspaceCreate(WorkspaceBase):
    usable_agent_ids: list[int] = 

class WorkspaceUpdate(DTOBase):
    name: str | None = None
    directory: str | None = None
    usable_agent_ids: list[int] | None = None

# agent.py
from . import DTOBase
from .provider import LlmModelRead
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from .workspace import WorkspaceRead

class AgentBase(DTOBase):
    name: str
    system_prompt: str
    model_id: int | None = None

class AgentRead(AgentBase):
    id: int
    model: LlmModelRead | None = None
    workspaces: list[WorkspaceRead] = 

class AgentCreate(AgentBase):
    workspace_ids: list[int] = 

class AgentUpdate(DTOBase):
    name: str | None = None
    system_prompt: str | None = None
    model_id: int | None = None
    workspace_ids: list[int] | None = None

通过这种方式,我们可以在两个模块中互相使用对方定义的类型,而无需处理循环导入问题。这种方法在编写复杂的 Python 应用程序时非常有用,特别是当涉及到多个模块之间的相互依赖时。

标签: none

评论已关闭