我想使用importlib中的import_module导入模块。当我这样做时,找不到我从模块引用的文件。如果我通常从python shell导入我的模块(不使用main.py)它按预期工作。此外,如果我将MyModule.py的路径添加到sys.path它可以工作,但据我所知,我不应该这样做(在下面的代码中注释掉)。
如何通过import_module加载模块时,如何加载我的引用文件?
我有以下文件结构
main.py
subfolders
folder1
__init__.py
MyModule.py
hello.py
main.py
from importlib import import_module
modulename = 'subfolders.folder1.MyModule'
print("Import module ", modulename)
module = import_module(modulename)
m_instance = module.MyModule()
m_instance.module_hello()
MyModule.py
#This is the solution that works but feels wrong
#import os, sys
#sys.path.append(os.path.dirname(__file__))
from hello import hello_world
class MyModule(object):
def __init__(self):
print("Init MyModule")
def module_hello(self):
hello_world()
hello.py
def hello_world():
print("Hello World!")
当我跑步时,我得到:
c:\git\PythonImportTest>python main.py
Import module subfolders.folder1.MyModule
Traceback (most recent call last):
File "main.py", line 5, in <module>
module = import_module(modulename)
File "C:\Miniconda3\lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 986, in _gcd_import
File "<frozen importlib._bootstrap>", line 969, in _find_and_load
File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 665, in exec_module
File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
File "c:\git\PythonImportTest\subfolders\folder1\MyModule.py", line 5, in <module>
from hello import hello_world
ImportError: No module named 'hello'
答案 0 :(得分:2)
首先,您需要在subfolders
目录中放置一个空的__init__.py
。其次,您需要通过绝对导入或相对导入来导入hello
模块。
绝对导入:
from subfolders.folder1.hello import hello_world
相对导入:
from .hello import hello_world
您现在的方式是在顶级包中找到hello.py(main.py所在的位置)。因为在那里找不到你的错误。
关于Python3中相对导入的说明
您可以从Python2切换到Python3,这就是使用隐式相对导入时遇到麻烦的原因。正如PEP404所说:
在Python 3中,包中的隐式相对导入不再存在 可用 - 仅限绝对导入和显式相对导入 支持的。此外,星级导入(例如来自x import *)仅是 在模块级代码中允许。
意味着您的代码应该适用于Python2,但对于Python3,您必须使用上述选项之一。另见:Changes in import statement python3
答案 1 :(得分:1)
您的代码存在的问题是子文件夹是文件夹而不是包。如果您使用的是import_module,则只能在包中搜索子包。
解决方案: 在子文件夹文件夹中创建 init .py并在那里导入folder1。