我有:
mod = import_module('path.module')
之后,我想/需要做的事情:
from mod.script import func
但是那给了我:
ModuleNotFoundError: No module named 'mod.script'
警告:使用“ mod.script.func()”或类似的名称无法满足我的需要(项目约束),我搜索如何使用“ from”这样的语法[module_imported_from_importlib]导入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
有了这个,我需要运行: /block1/v1/script1.py中的/block2/v1/script2.py函数
我想做的是使用相同的语法指定script1应该在何处使用“ script2”(在v1或v2中,在block2中),但只指定不带版本的块(将会改变):
旧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 / init .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()
能够运行我的测试功能
非常感谢您的帮助,我不知道这很清楚!
答案 0 :(得分:0)
经过大量测试,我终于找到了不错的东西。
如果要使用带有自定义名称的自定义模块,最好的方法是创建一个模块,并给他指定您想要的名称: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')
使用此选项,我可以保留所有导入内容,仅在“管理器”文件中指定版本,例如:
block1 / v1 / script1.py:
from GLOBALCONFIG.module_manager.block1 import block2
from block2 import script2
如果我将script2放在block2 / v2或/ v3或任何版本中,我只需要更改正确的版本以将其用于block1.py管理器中的block2,代码仍然可以工作
此外,如果需要的话:
使用block2 / v1的block1 / v1
使用block2 / v2的block1 / 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
block1 => block1 / v1
block2 => block2 / v1
但是这是神奇的把戏:
在block1 / v2 /script1.py中:
import sys
sys.argv[0] = __file__
from GLOBALCONFIG.module_manager.block1 import block1, block2
block1 => block1 / v2
block2 => block2 / v2
版本不同但代码完全相同
FYI:强制使用当前文件路径的sys.argv [0] = 文件对我来说是强制性的,这是因为我的服务开始使用gunicon wsgi:app,该默认路径位于[venv] / bin / gunicorn,但没有这个限制,GLOBALCONFIG导入应该可以正常工作
此致