在Python应用程序中导入子子包

时间:2012-10-30 21:28:59

标签: python python-module python-import

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

    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 Layer4Manager之类的操作,其中Layer4Managermodules/layer4/layer4.py内的一个类。如果可能的话,我不想在__init__.py内包含实际代码,因为在同一目录中会有其他脚本/文件,因此将它们组合在目录中是有意义的(这也是为什么脚本不只是在modules目录中。

  • iptables.pylayer4.py应该可以从utils.py导入功能。

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

我一直在与这个争斗几个小时,我无法让所有上述三件物品同时工作。在from layer4 import *中使用__all__modules/layer4/__init__.py变量可以打破测试,因为他们无法from myapp.utils import UtilityFunction

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

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

提前致谢!

2 个答案:

答案 0 :(得分: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

并且所有这些都可以正常运行

答案 1 :(得分:0)

“来自modules.layer4.layer4 import Layer4Manager”应该适用于您的第一次导入 - 不是,或者这还不够?

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

中进行导入时测试会中断

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

相关问题