1

我正在编写一个模块化应用程序,它将在运行时根据启动参数等动态导入模块。为了使事情井井有条,我有以下目录结构:

    myapp/
    ├── __init__.py
    ├── main.py
    ├── utils.py
    ├──modules/
        ├── __init__.py
        ├── iptables/
        │   ├── __init__.py
        │   ├── iptables.py
        │   ├── [other files/directories/configuration...]
        │   └── tests
        │       ├── iptables_tests.py
        ├── layer4/
        │   ├── __init__.py
        │   ├── layer4.py
        │   ├── [other files/directories/configuration...]
        │   └── tests
        │       ├── layer4_tests.py

我正在尝试完成以下任务:

  • main.py应该可以做一些类似的事情from modules.layer4 import Layer4ManagerLayer4Manager里面有一个类modules/layer4/layer4.py。如果可能的话,我想在不包含实际代码的情况下执行此操作__init__.py,因为同一目录中还会有其他脚本/文件,因此将它们组合在目录中是有意义的(这也是脚本不包含的原因t 只是在modules目录中)。

  • iptables.py并且layer4.py应该能够从utils.py.

  • 使用 Python unittest 框架和 Nose 的测试应该能够正确运行,例如,iptables_tests.py应该能够运行from myapp.modules.iptables import IPTablesControllerfrom myapp.utils import UtilityFunction.

我已经为此奋斗了几个小时,但我无法让上述所有三个项目同时工作。使用from layer4 import *or__all__里面的变量modules/layer4/__init__.py会破坏测试,因为它们无法from myapp.utils import UtilityFunction.

消隐modules/*/__init__.py使我无法做到from myapp.modules.layer4 import Layer4Manager

我尝试了其他几种组合,我认为我只是让事情变得更糟。我的目标是 Python 2.6。我猜某种相对导入会使事情变得更容易,但我不确定它们如何与我在这里使用的两级目录结构一起工作。

提前致谢!

4

2 回答 2

0

您不需要main/__init__.py,因为您不想制作myapp包,并且当您执行 main.py 时,myapp 将自动添加到 python 路径中。

除了看起来不错之外,如果您放置正确的路径,您应该能够直接从子包中导入模块,例如

import utils
from modules.layer4 import layer4

我创建了一个类似的结构,它运行良好,例如

$ cat myapp/main.py 
import utils
from modules.layer4 import layer4
from modules.iptables import iptables

$ cat myapp/modules/iptables/iptables.py
from modules.layer4 import layer4

$ cat myapp/modules/layer4/layer4.py
import utils

所有这一切都没有错误

于 2012-10-30T21:36:52.750 回答
0

“from modules.layer4.layer4 import Layer4Manager”应该适用于您的第一次导入 - 它不是,还是不够?

您的 utils.py 是否也从它下面的任何模块导入?如果是这样,您可能正在创建循环导入(只是一个猜测,但这可能是为什么您不能同时让所有导入工作......)。如果是这样,您可能需要将导入移动到代码块中,它们不会在导入 utils.py 时执行。这可以解释为什么在 __init__.py 中进行导入时测试会中断。

否则,如果你想让“from modules.layer4 import Layer4Manager”工作,你真的需要以某种方式将它带入 __init__.py - 可能通过在那里导入。

于 2012-10-30T21:40:34.367 回答