我正在编写一个模块化应用程序,它将根据启动参数等在运行时动态导入模块。为了保持组织有序,我有以下目录结构:
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
之类的操作,其中Layer4Manager
是modules/layer4/layer4.py
内的一个类。如果可能的话,我不想在__init__.py
内包含实际代码,因为在同一目录中会有其他脚本/文件,因此将它们组合在目录中是有意义的(这也是为什么脚本不只是在modules
目录中。
iptables.py
和layer4.py
应该可以从utils.py
导入功能。
使用Python unittest框架和Nose的测试应该正确运行,例如,iptables_tests.py
应该能够运行from myapp.modules.iptables import IPTablesController
和from 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。我猜某种相对导入会让事情变得更容易,但我不确定他们如何使用我在这里使用的两级目录结构。
提前致谢!
答案 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 - 可能是通过那里的导入。