ModuleNotFoundError 在从 importlib 导入的模块上使用 "classic" import
ModuleNotFoundError using "classic" import on module imported from importlib
TL,DR
我已经:
mod = import_module('path.module')
在那之后,我want/need要做的事情:
from mod.script import func
但这给了我:
ModuleNotFoundError: No module named 'mod.script'
Warning :使用 "mod.script.func()" 或类似的东西调用它不符合我的需要(项目约束),我搜索如何使用像 "from [module_imported_from_importlib] import XXX"
简介:
我需要将现有代码拆分到具有多个版本的不同文件夹中。目标是在应用程序中拥有不同的部分,每个部分都使用其他部分的指定版本。
示例树:
ref.py
block1
__init__.py
- v1
| __init__.py
|- __init__.py
|- script1.py
block2
__init__.py
- v1
| __init__.py
|-- __init__.py
|-- script2.py
- v2
|- __init__.py
|-- __init__.py
|-- script2.py
有了这个,我需要 运行 :
/block2/v1/script2.py 函数在 /block1/v1/script1.py
中
目标
我尝试做的是使用相同的语法指定 script1 应该在哪里使用 "script2"(在 block2 中的 v1 或 v2 中),但只是指定没有版本的块(那会改变):
旧 script1.py :
from script2 import <func>
新script1.py
from block2.script2 import <func>
代码
我已经尝试了很多事情都没有成功,现在我在这里似乎接近解决方案但我找不到它(也许这是不可能的?):
在block1/v1/init.py :
from importlib import import_module, reload
MODULE = import_module('block2.v1') # With 'block2.v1' defined as a variable somewhere else (eg in ref.py)
reload(MODULE)
在block1/v1/script1.py中:
from block1.v1 import MODULE as block2
print(block2)
print(f'block2 : {dir(block2)}')
from block2.script2 import test
在block2/v1/初始化.py :
from block2.v1 import script2
print(script2)
在block2/v1/script2.py中:
def test():
print("hello")
结果 # python block1/v1/script1.py :
<module 'block2.v1.script2' from 'xxx/block2/v1/script2.py'>
<module 'block2.v1.script2' from 'xxx/block2/v1/script2.py'>
<module 'block2.v1' from 'xxx/block1/v1/__init__.py'>
block2 : ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'script2']
Traceback (most recent call last):
File "block1/v1/script1.py", line 17, in <module>
from block2.script2 import test
ModuleNotFoundError: No module named 'block2.script2'
预期结果
很快,我希望在脚本 1 中有这个调用语法:
from block2.script2 import test
test()
能够运行我的测试功能
非常感谢帮助,我不知道它是否真的很清楚!
经过大量测试,我终于找到了一个不错的东西。
如果你想使用自定义名称的自定义模块,最好的办法是创建一个模块并给他你想要的名称:D
树:
/GLOBALCONFIG
|- /module_manager
|- block1.py
|- block2.py
|- blocX..
- module_version_manager
/block1
|- /v1
|- script1.py
|- /v2
|- script1.py
/block2
|- /v1
|- script2.py
|- /v2
|- script2.py
为此,我在项目根目录下创建了一个名为 "GLOBALCONFIG" 的目录,其中包含一个 .py 管理器:
from importlib import import_module
import sys
import os
block1 = sys.modules['block1'] = import_module('block1.v1')
block2 = sys.modules['block2'] = import_module('block2.v1')
使用它,我可以保留所有导入,仅在 "manager" 文件中指定版本,例如:
block1/v1/script1.py :
from GLOBALCONFIG.module_manager.block1 import block2
from block2 import script2
如果我将 script2 放入 block2/v2 或 /v3 或任何,我只需要更改正确的版本以用于 block1.py 管理器中的 block2 并且代码仍然有效
另外,如果你想:
block1/v1 使用 block2/v1
block1/v2 使用 block2/v2
您可以创建一个引用全局配置中的模块/版本的字典:
module_version_manager.py :
block1_modules_versions = {
'block1.v1': {
'block2':'block2.v1',
}
'block1.v2': {
'block2':'block2.v2',
}
}
block2_modules_versions = {
'block2.v2': {
'block1':'block1.v1',
}
'block2.v2': {
'block1':'block1.v2',
}
}
然后,在您的 block1.py 经理中:
from GLOBALCONFIG.module_version_manager import block1_modules_versions
from importlib import import_module
import sys
import os
block1 = sys.modules['u1'] = import_module('.'.join(str.rsplit(sys.argv[0], "/")[3:5])) # give me the current version of the current block : block1.vX
block2 = sys.modules['block2'] = import_module(block1_modules_versions['.'.join(str.rsplit(sys.argv[0], "/")[3:5])]['block2']) # give me the block2 to use for the right block1.vX
在block1/v1/script1.py 中:
import sys
sys.argv[0] = __file__ # [path]/block1/v1/script1 => current path of executed script giving the right folder and import the right modules
from GLOBALCONFIG.module_manager.block1 import block1, block2
块 1 => block1/v1
block2 => block2/v1
但是这是一个神奇的技巧 :
在 block1/v2/script1.py 中:
import sys
sys.argv[0] = __file__
from GLOBALCONFIG.module_manager.block1 import block1, block2
块 1 => block1/v2
block2 => block2/v2
版本不同但代码完全相同
仅供参考:强制当前文件路径的 sys.argv[0] = file 对我来说是强制性的,因为我的服务开始使用 gunicon wsgi:app在 [venv]/bin/gunicorn 处设置了默认路径,但没有此约束,GLOBALCONFIG 导入应该可以很好地工作
此致,
TL,DR
我已经:
mod = import_module('path.module')
在那之后,我want/need要做的事情:
from mod.script import func
但这给了我:
ModuleNotFoundError: No module named 'mod.script'
Warning :使用 "mod.script.func()" 或类似的东西调用它不符合我的需要(项目约束),我搜索如何使用像 "from [module_imported_from_importlib] import XXX"
简介:
我需要将现有代码拆分到具有多个版本的不同文件夹中。目标是在应用程序中拥有不同的部分,每个部分都使用其他部分的指定版本。
示例树:
ref.py
block1
__init__.py
- v1
| __init__.py
|- __init__.py
|- script1.py
block2
__init__.py
- v1
| __init__.py
|-- __init__.py
|-- script2.py
- v2
|- __init__.py
|-- __init__.py
|-- script2.py
有了这个,我需要 运行 : /block2/v1/script2.py 函数在 /block1/v1/script1.py
中目标
我尝试做的是使用相同的语法指定 script1 应该在哪里使用 "script2"(在 block2 中的 v1 或 v2 中),但只是指定没有版本的块(那会改变):
旧 script1.py :
from script2 import <func>
新script1.py
from block2.script2 import <func>
代码
我已经尝试了很多事情都没有成功,现在我在这里似乎接近解决方案但我找不到它(也许这是不可能的?):
在block1/v1/init.py :
from importlib import import_module, reload
MODULE = import_module('block2.v1') # With 'block2.v1' defined as a variable somewhere else (eg in ref.py)
reload(MODULE)
在block1/v1/script1.py中:
from block1.v1 import MODULE as block2
print(block2)
print(f'block2 : {dir(block2)}')
from block2.script2 import test
在block2/v1/初始化.py :
from block2.v1 import script2
print(script2)
在block2/v1/script2.py中:
def test():
print("hello")
结果 # python block1/v1/script1.py :
<module 'block2.v1.script2' from 'xxx/block2/v1/script2.py'>
<module 'block2.v1.script2' from 'xxx/block2/v1/script2.py'>
<module 'block2.v1' from 'xxx/block1/v1/__init__.py'>
block2 : ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'script2']
Traceback (most recent call last):
File "block1/v1/script1.py", line 17, in <module>
from block2.script2 import test
ModuleNotFoundError: No module named 'block2.script2'
预期结果
很快,我希望在脚本 1 中有这个调用语法:
from block2.script2 import test
test()
能够运行我的测试功能
非常感谢帮助,我不知道它是否真的很清楚!
经过大量测试,我终于找到了一个不错的东西。
如果你想使用自定义名称的自定义模块,最好的办法是创建一个模块并给他你想要的名称:D
树:
/GLOBALCONFIG
|- /module_manager
|- block1.py
|- block2.py
|- blocX..
- module_version_manager
/block1
|- /v1
|- script1.py
|- /v2
|- script1.py
/block2
|- /v1
|- script2.py
|- /v2
|- script2.py
为此,我在项目根目录下创建了一个名为 "GLOBALCONFIG" 的目录,其中包含一个 .py 管理器:
from importlib import import_module
import sys
import os
block1 = sys.modules['block1'] = import_module('block1.v1')
block2 = sys.modules['block2'] = import_module('block2.v1')
使用它,我可以保留所有导入,仅在 "manager" 文件中指定版本,例如:
block1/v1/script1.py :
from GLOBALCONFIG.module_manager.block1 import block2
from block2 import script2
如果我将 script2 放入 block2/v2 或 /v3 或任何,我只需要更改正确的版本以用于 block1.py 管理器中的 block2 并且代码仍然有效
另外,如果你想:
block1/v1 使用 block2/v1
block1/v2 使用 block2/v2
您可以创建一个引用全局配置中的模块/版本的字典:
module_version_manager.py :
block1_modules_versions = {
'block1.v1': {
'block2':'block2.v1',
}
'block1.v2': {
'block2':'block2.v2',
}
}
block2_modules_versions = {
'block2.v2': {
'block1':'block1.v1',
}
'block2.v2': {
'block1':'block1.v2',
}
}
然后,在您的 block1.py 经理中:
from GLOBALCONFIG.module_version_manager import block1_modules_versions
from importlib import import_module
import sys
import os
block1 = sys.modules['u1'] = import_module('.'.join(str.rsplit(sys.argv[0], "/")[3:5])) # give me the current version of the current block : block1.vX
block2 = sys.modules['block2'] = import_module(block1_modules_versions['.'.join(str.rsplit(sys.argv[0], "/")[3:5])]['block2']) # give me the block2 to use for the right block1.vX
在block1/v1/script1.py 中:
import sys
sys.argv[0] = __file__ # [path]/block1/v1/script1 => current path of executed script giving the right folder and import the right modules
from GLOBALCONFIG.module_manager.block1 import block1, block2
块 1 => block1/v1
block2 => block2/v1
但是这是一个神奇的技巧 :
在 block1/v2/script1.py 中:
import sys
sys.argv[0] = __file__
from GLOBALCONFIG.module_manager.block1 import block1, block2
块 1 => block1/v2
block2 => block2/v2
版本不同但代码完全相同
仅供参考:强制当前文件路径的 sys.argv[0] = file 对我来说是强制性的,因为我的服务开始使用 gunicon wsgi:app在 [venv]/bin/gunicorn 处设置了默认路径,但没有此约束,GLOBALCONFIG 导入应该可以很好地工作
此致,