【问题标题】:Pythonic Way to structure module API with circular import使用循环导入构建模块 API 的 Pythonic 方式
【发布时间】:2019-03-14 19:53:57
【问题描述】:

我应该如何解决以下循环依赖?

我有一个文件 A,它公开 API 方法并将所有后端逻辑委托给一个单独的文件 A_impl。

在 A.py 中,我还公开了一个 Enum,客户端需要将其作为参数传递给某些 API 方法:

# A.py
import A_impl

class MyEnum(Enum):
    ONE = 1
    TWO = 2
    THREE = 3

def A(x: MyEnum):
    return A_impl._A(x)

A_impl 实际上需要 MyEnum:

#A_impl.py
from A import MyEnum

def _A(x: MyEnum):
    pass

解决此问题的一种方法是将两个模块合并在一起,但这违背了首先将其拆分为更简洁代码的目的。 A_impl 由数十个辅助函数组成,将公共和私有方法放在一个模块中变得很混乱。

【问题讨论】:

  • 你能把MyEnum 类放在A.pyA_impl.py 都从中导入的第三个文件中吗?

标签: python python-3.x circular-dependency


【解决方案1】:

您可以改为在A 的定义中导入A_impl

# A.py

class MyEnum(Enum):
    ONE = 1
    TWO = 2
    THREE = 3

def A(x: MyEnum):
    import A_impl
    return A_impl._A(x)

【讨论】:

  • 我很确定您需要在定义 _A 函数时让 MyEnum 可用,否则类型提示将不知道 MyEnum 类是什么。
  • 不,你不能,因为函数注释中的MyEnum 是在函数定义时评估的。导入模块时你会得到一个NameError
  • 还有其他方法吗?如果我有 10 个 API 方法,那么我需要导入 10x 感觉有点傻
  • @vgbcell 也可以在不导入A.py的单独模块中定义MyEnum,避免循环导入。
  • @blhsing 我也想到了。无论如何,在函数内部进行导入的后果是什么?如果 A() 被多次调用,是否每次调用 A() 时都会导入整个模块?或者是否有一些进口缓存机制?导入 A_impl 的多个函数的相同问题
猜你喜欢
  • 2012-09-10
  • 1970-01-01
  • 1970-01-01
  • 2023-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
相关资源
最近更新 更多