由 import_module 加载时从模块引用 python 文件
Referencing a python file from a module when loaded by import_module
我想使用 import_module 从 importlib 导入一个模块。当我这样做时,找不到我从我的模块引用的文件。如果我从 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'
首先,您需要通过在其中放置一个空 __init__.py
来使您的 subfolders
目录成为一个包。其次,您需要通过绝对导入或相对导入来导入 hello
模块。
绝对导入:
from subfolders.folder1.hello import hello_world
相对导入:
from .hello import hello_world
你现在的做法是在你的顶级包中寻找 hello.py(你的 main.py 所在的位置)。因为在那里找不到它,所以你会得到一个错误。
关于 Python3
中相对导入的说明
你可能从 Python2 切换到 Python3 这就是为什么你在使用隐式相对导入时遇到麻烦的原因。正如 PEP404 所说:
In Python 3, implicit relative imports within packages are no longer
available - only absolute imports and explicit relative imports are
supported. In addition, star imports (e.g. from x import * ) are only
permitted in module level code.
意味着您的代码应该适用于 Python2,但对于 Python3,您必须使用上述选项之一。另见:Changes in import statement python3
您的代码存在的问题是子文件夹是文件夹而不是包。如果您使用 import_module,则只能在包中搜索子包。
解决方法:
在您的子文件夹中创建一个 init.py 并在那里导入 folder1。
我想使用 import_module 从 importlib 导入一个模块。当我这样做时,找不到我从我的模块引用的文件。如果我从 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'
首先,您需要通过在其中放置一个空 __init__.py
来使您的 subfolders
目录成为一个包。其次,您需要通过绝对导入或相对导入来导入 hello
模块。
绝对导入:
from subfolders.folder1.hello import hello_world
相对导入:
from .hello import hello_world
你现在的做法是在你的顶级包中寻找 hello.py(你的 main.py 所在的位置)。因为在那里找不到它,所以你会得到一个错误。
关于 Python3
中相对导入的说明你可能从 Python2 切换到 Python3 这就是为什么你在使用隐式相对导入时遇到麻烦的原因。正如 PEP404 所说:
In Python 3, implicit relative imports within packages are no longer available - only absolute imports and explicit relative imports are supported. In addition, star imports (e.g. from x import * ) are only permitted in module level code.
意味着您的代码应该适用于 Python2,但对于 Python3,您必须使用上述选项之一。另见:Changes in import statement python3
您的代码存在的问题是子文件夹是文件夹而不是包。如果您使用 import_module,则只能在包中搜索子包。
解决方法: 在您的子文件夹中创建一个 init.py 并在那里导入 folder1。