从另一个文件夹导入模块时导入错误

时间:2016-03-11 10:31:37

标签: python

我有以下文件夹结构:

controller/
    __init__.py
    reactive/
        __init__.py
        control.py
pos/
    __init__.py
    devices/
        __init__.py
        cash/
            __init__.py
            server/
                __init__.py
                my_server.py
    dispatcher/
        __init__.py
        dispatcherctrl.py

我需要导入control.py中的模块my_server.py,但它说ImportError: No module named controller.reactive.control,尽管我已在所有文件夹中添加__init__.pysys.path.append('/home/other/folder/controller/reactive') } my_server.py

主文件位于my_server.py

我不明白为什么,因为dispatcherctrl.py执行相同的导入并且工作正常。

1 个答案:

答案 0 :(得分:1)

在Python3中

您可以使用importlib.machinery模块为导入创建命名空间和绝对路径:

import importlib.machinery

loader = importlib.machinery.SourceFileLoader('control', '/full/path/controller/reactive/control.py')
control = loader.load_module('control')

control.someFunction(parameters, here)

此方法可用于以任何方式在任何文件夹结构中导入内容(向后,递归 - 并不重要,我在这里使用绝对路径只是为了确定)。

Python2

感谢Sebastian为Python2提供类似的答案:

import imp

control = imp.load_source('module.name', '/path/to/controller/reactive/control.py')
control.someFunction(parameters, here)

跨版本方式

你也可以这样做:

import sys
sys.path.insert(0, '/full/path/controller')

from reactive import control # <-- Requires control to be defined in __init__.py
                                                # it is not enough that there is a file called control.py!

重要!sys.path的开头插入路径可以正常工作,但是如果您的路径包含任何与Python内置函数冲突的内容,那么您将破坏那些内置函数可能会导致各种各样的问题。为此,尝试尽可能多地使用导入机制,并回归到跨版本的方式。