首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >循环导入的python解决方案

循环导入的python解决方案
EN

Stack Overflow用户
提问于 2015-07-13 19:41:53
回答 4查看 9K关注 0票数 6

好的,就是这样。

我不想泄露我的代码,但是如果你真的需要,我会的。我有两个模块,彼此需要一点。这些模块称为the处理程序和数据处理程序。

在网络处理程序中,我有一行:

代码语言:javascript
复制
import datahandler 

在数据处理程序中,我有另一行:

代码语言:javascript
复制
import webhandler

现在,我知道这是非常糟糕的代码,这样的循环导入会导致代码运行两次(这正是我试图避免的)。

但是,数据处理程序模块需要访问来自webhandler模块的多个函数,而webhandler模块需要访问在数据处理程序模块中生成的多个变量。除了将函数移动到不同的模块之外,我看不到任何其他的解决办法,但这会破坏我的程序的组织,并且对模块命名没有任何逻辑意义。

有什么帮助吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-07-13 19:51:05

循环依赖是代码嗅觉的一种形式。如果您有两个相互依赖的模块,那么这是一个非常糟糕的迹象,您应该重构您的代码。

有几种不同的方法可以做到这一点;哪一种是最好的取决于您正在做什么,以及每个模块的哪些部分实际上是由另一个模块使用的。

  • 一个非常简单的解决方案是将两个模块合并,所以您只有一个模块,它只依赖于自己,或者更确切地说,取决于它自己的内容。这很简单,但是由于您以前已经分离了模块,所以您可能会以这种方式引入新的问题,因为您不再将关注点分离开来。
  • 另一种解决方案是确保实际需要依赖项。如果一个模块中只有几个部分依赖于另一个模块,也许您可以以不再需要循环依赖的方式移动这些比特,或者利用导入工作的方式使循环依赖不再是一个问题。
  • 更好的解决方案可能是将依赖项移动到单独的新模块中。如果命名确实是最难的问题,那么您可能做得很好。它可能会“破坏你的程序的组织”,但由于你有循环的依赖关系,你的设置有一些固有的错误。
票数 10
EN

Stack Overflow用户

发布于 2015-07-13 20:21:49

其他人所说的不执行循环导入是最好的解决方案,但是如果您最终绝对需要它们(可能是为了向后兼容性或代码的清晰性),它通常在其中一个模块的一个方法或功能中。因此,您可以安全地这样做:

代码语言:javascript
复制
# modA.py
import modB

# modB.py
def functionDependingOnA():
    import modA
    ...

每次调用函数时,执行导入的开销都很小,但是除非一直调用它,否则它是相当低的。(在我的测试中大约有400 in )。

为了避免这种查找,您也可以这样做:

代码语言:javascript
复制
# modA -- same as above.

# modB.py
_imports = {}

def _importA():
    import modA
    _imports['modA'] = modA
    return modA

def functionDependingOnA():
    modA = _imports.get('modA') or _importA()

该版本只在第二次调用和后续调用上增加了40 as的时间,或者与空的本地函数调用的时间相同。

票数 7
EN

Stack Overflow用户

发布于 2019-10-22 13:16:26

SqlAlchemy使用依赖项注入模式,其中所需的模块由装饰器传递给函数:

代码语言:javascript
复制
@util.dependencies("sqlalchemy.orm.util")
def identity_key(cls, orm_util, *args, **kwargs):
    return orm_util.identity_key(*args, **kwargs)

这种方法基本上与在函数中执行import相同,但性能稍微好一些。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31392035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档