繁体   English   中英

如何正确处理 Python 中的循环模块依赖?

[英]How to properly handle a circular module dependency in Python?

试图找到一个好的和合适的模式来处理 Python 中的循环模块依赖。 通常,解决方法是将其移除(通过重构); 然而,在这种特殊情况下,我们真的希望拥有需要循环导入的功能。

编辑:根据下面的答案,此类问题的常见攻击角度是重构。 但是,对于这个问题,假设这不是一个选项(无论出于何种原因)。

问题:

logging模块的某些配置数据需要configuration模块。 但是,对于某些configuration功能,我真的很想使用在logging模块中定义的自定义日志功能。 显然,在configuration导入logging模块会引发错误。

我们可以想到的可能解决方案:

  1. 不要这样做 正如我之前所说,这不是一个好的选择,除非所有其他可能性都很丑陋和糟糕。

  2. 猴子补丁模块 这听起来并不太坏:加载logging动态模块插入configuration初始导入,和之前的任何职能被实际使用。 不过,这意味着定义全局的、每个模块的变量。

  3. 依赖注入 我已经阅读并遇到了依赖注入替代方案(特别是在 Java Enterprise 领域),它们消除了一些令人头疼的问题; 但是,它们的使用和管理可能过于复杂,这是我们希望避免的。 不过,我不知道 Python 中的全景图如何。

启用此功能的好方法是什么?

非常感谢!

如前所述,可能需要进行一些重构。 从名字上看,如果一个日志模块使用配置可能是可以的,当考虑配置中应该有什么东西时,就会想到配置参数,那么问题就来了,为什么要配置日志?

使用日志记录的配置下的代码部分可能不属于配置模块:似乎它正在执行某种处理并记录结果或错误。

没有内部知识,仅使用常识,“配置”模块应该是简单的东西,没有太多处理,它应该是导入树中的叶子。

希望能帮助到你!

这对你有用吗?

# MODULE a (file a.py)
import b
HELLO = "Hello"

# MODULE b (file b.py)
try:
    import a
    # All the code for b goes here, for example:
    print("b done",a.HELLO))
except:
    if hasattr(a,'HELLO'):
        raise
    else:
        pass

现在我可以做一个导入 b。 当循环导入(由 a 中的 import b 语句引起)抛出异常时,它会被捕获并丢弃。 当然,您的整个模块 b 必须缩进一个额外的块间距,并且您必须了解变量 HELLO 在 a 中声明的位置。

如果你不想通过插入 try:except: 逻辑来修改 b.py,你可以将整个 b 源移动到一个新文件中,将其命名为 c.py,然后制作一个简单的文件 b.py,如下所示:

# new Module b.py
try:
    from c import *
    print("b done",a.HELLO) 
except:
    if hasattr(a,"HELLO"):
        raise
    else:
        pass

# The c.py file is now a copy of b.py:
import a
# All the code from the original b, for example:
print("b done",a.HELLO))

这会将整个命名空间从 c 导入到 b,并覆盖循环导入。

我知道这很恶心,所以不要告诉任何人。

循环模块依赖通常是一种代码味道。

它表示应该重构部分代码,以便它在两个模块之外。

因此,如果我正确阅读了您的用例,则logging访问configuration以获取配置数据。 但是, configuration有一些函数,当调用时,需要将logging中的内容导入configuration

如果是这种情况(也就是说,在开始调用函数之前, configuration并不真正需要logging ),答案很简单:在configuration ,将所有来自logging的导入放在文件的底部,毕竟是类、函数和常量定义。

Python 从上到下读取内容:当它在configuration遇到import语句时,它会运行它,但此时, configuration已经作为可以导入的模块存在,即使它还没有完全初始化:它只有在import语句运行之前声明的属性。

不过,我确实同意其他人的看法,循环导入通常是一种代码气味。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM