【问题标题】:ImportError on cross import modules交叉导入模块上的 ImportError
【发布时间】:2019-05-20 10:15:02
【问题描述】:

我对 Python 中的整个交叉导入感到很困惑。我有一个包含一个主模块 ma​​in.py 和几个子模块 b.pyc.py 的包,每个模块都有一个类模块分别为class mainclass bclass c

__init__.py 中:

from .main import main
from .b import b
from .c import c

ma​​in.py 中:

from .b import b 
from .c import c
class main:

b.py中:

from .main import main 
class b:

会引发 ImportError,我们可以解决它:

class b:
    def __init__(self):
        from .main import main

这样就好了。但我不太明白为什么。如果我在 b.py 中有多个类或方法,该怎么办。在每种方法中使用 import main 会非常低效甚至影响性能吗?

非常感谢。

【问题讨论】:

    标签: python


    【解决方案1】:

    Python 不是 Java,既不要求也不推荐使用“每个类一个模块”方案 - 实际上恰恰相反 - 并且无论如何都不支持循环依赖 - 正如您已经发现的那样。 IOW,如果您有两个相互依赖的类(或函数或其他任何东西),那么它们显然应该存在于同一个模块中(无论如何这是“低耦合,高内聚”规则所要求的)。

    在函数或方法体中导入被认为是不好的做法,确实会在每次调用时增加一些开销(不是那么多开销,但在一个巨大的数据集上的紧密循环中它可以产生很大的不同),并且实际上应该只是用作最后的临时 Q&D hack。

    你有什么建议可以减少模块的混乱,因为把它们放在一个模块中会导致一个非常大的文件有太多的行(至少在我看来)

    如果不知道代码实际是什么样子就不可能回答这个问题,但是如果 3 个(三个!)类足以达到您的“太多行”限制,那么您的类很可能做得太多并且会受益于被重构为不同的类(可能还有普通函数——python 并不要求所有代码都存在于类中),其中一些可能会被提取到其他实用程序模块中。 “单一责任”原则在这里是一个很好的指南......您可能还有一些可以以更简洁(但仍然可读)的方式重写的代码 - 看起来您对 Python 没有太多经验,很可能您'没有利用完整的语言(和标准库)功能。

    现在,有时即使有最好的设计和编码,你仍然会得到相当大的模块,因为这个领域本质上很复杂,需要相当多的代码......这是生活中的一个事实,你必须学会​​忍受,对不起。

    哦,是的:当然,这还取决于您是否认为“太大而无法满足您的喜好”——据记录,1000 多行的模块非常普通。

    【讨论】:

    • 非常感谢。这是有道理的。但是,您会建议如何使模块不那么混乱,因为将它们放在一个模块中会导致文件非常大,而且行数过多(至少在我看来)难以管理。
    猜你喜欢
    • 2012-10-04
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-08
    相关资源
    最近更新 更多