Python模块(部分)彼此导入

时间:2015-09-28 18:41:13

标签: python python-module

我将一个大型项目(对我而言!)分解为2个或3个模块,其中包括一个' main'具有顶级菜单等的模块。它将导入两个或三个子模块'对于应用程序的不同方面。但是,这些模块将需要来自主模块的各种设置等。是的,它们可以作为参数传递,但是它们中有很多并且它们可能会发生变化。不同的模块需要不同的设置子集。

我希望能够让下属模块简单地“回归”。根据需要进行设置(按模块划分全局模块)。

以下是我所说的mickie-mouse示例:

TEST1:

# dummy version of main / sub modules with mutual importing
# this is the 'main module'
# in this trivial example, it would be easy to make mode an argument of the function
# but as an alternatiove can test2 'reach back' to test1? 

from test2 import taskA
mode = 1
ans = taskA()
print(ans)

TEST2:

# dummy version of main / sub modules with mutual importing
# this is the 'sub module' that executes taskA

from test1 import mode

def taskA():
    print('taska, mode = {0}'.format(mode))    
    return 'Hello World!'

mode = 0
print('test2 initialised')

结果是

Traceback (most recent call last):
  File "C:\Python33\MyScripts\test1.py", line 6, in <module>
    from test2 import taskA
  File "C:\Python33\MyScripts\test2.py", line 4, in <module>
    from test1 import mode
  File "C:\Python33\MyScripts\test1.py", line 6, in <module>
    from test2 import taskA
ImportError: cannot import name taskA

据推测,这是由于潜在的循环性。 (虽然,如果它能够检测圆度 - 在这种情况下并不难!即,任务A已经被导入,你认为它能够简单地突破圆形,而不是抛出错误)。

有没有办法实现这个目标?有几种明显的代码编码方式 - 将其作为一个模块;将设置作为参数传递(但是如果&#39; test2&#39;必须修改任何设置,那将会有陷阱,如果只是因为我仍然关注python对可变对象和绑定的处理);将所有设置移动到test1和test2访问的单独模块(test0)。

鉴于这些模块密切相关(我相信这个术语是强耦合的),逻辑上它应该都是一个模块。除了变大。

我的问题是双重的......如何最好地做我想要的事情;还要理解为什么Python无法处理相互导入。

1 个答案:

答案 0 :(得分:1)

(1)尝试在导入之前移动“mode = 1”行。这使它不再依赖于import语句。

(2)如果这不起作用,将模式放入一个单独的包中,并从那里同时具有test1和test2导入模式。

基本问题是你混合了依赖程度。您在“模式”和该模块中的其他项目之间创建了一个人为链接。

我没看到你在设置“模式”时遇到麻烦;我第一次尝试就做得很好。

test0.py

mode = 2

test1.py

from test0 import mode
from test2 import taskA
mode = 1
ans = taskA()
print(ans)

test2.py

from test0 import mode
def taskA():
    print('taska, mode = {0}'.format(mode))
    return 'Hello World!'

mode = 0
print('test2 initialised')

执行

>>> python2.7 test1.py
test2 initialised
taska, mode = 0
Hello World!

&gt;&gt;&gt;

在您的原始示例中: (A)在test1.py中,将mode = 1行移到导入之前:

mode = 1

from test2 import taskA
ans = taskA()
print(ans)

此开关显示该模式不能依赖于模块taskA中的任何内容,从而打破了病态循环依赖。

(B)使用 test2.py 作为顶级模块运行程序:

>>> python2.7 test2.py
test2 initialised
taska, mode = 0
Hello World!
test2 initialised

这会让你到达目的地吗?

通常,您应该在有向非循环图(DAG)中设计依赖项。 C可以是简单的,但很好用,分隔标题( .h)和代码( .c)文件。这就是为什么我建议第三个文件保存你的“模式”声明。