在Python中导入另一个模块中的模块



我很难把一些实用程序代码作为一个模块分开。我的文件结构如下:

scripts/
|
+-- toggle_keyboard.py
PyUtils/
|
+-- sistema.py
+-- strings.py
+-- test_sistema.py

Sistema.py需要在strings.py中有一个类,所以它以

开头:
from strings import String

并且Pytest testrongistema.py需要sistema.py,所以它以:

开头
import sistema as sis

现在,当我使用PyTest运行测试时,这一切都很好。然而,我不能在toggle_keyboard.py中使用这个模块。我以:

开头
import PyUtils.sistema as sis

没有编译错误。然而,当我运行它时,我得到的结果是:

Traceback (most recent call last):
File "toggle_keyboard.py", line 2, in <module>
import PyUtils.sistema as sis
File "/home/xxxxxx/scripts/PyUtils/sistema.py", line 2, in <module>
from strings import String
ModuleNotFoundError: No module named 'strings'

在网上搜索类似的问题,我发现利用"相对导入"可以解决问题。实际上,我能够运行toggle_keyboard.py时,我改变了sistema.py:

from .strings import String

然而,测试不再运行。当我现在执行PyTest时,我得到:

Traceback:
/usr/lib/python3.6/importlib/__init__.py:126: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
PyUtils/test_sistema.py:1: in <module>
import sistema as sis
PyUtils/sistema.py:2: in <module>
from .strings import String
E   ImportError: attempted relative import with no known parent package

使主脚本和模块的测试工作的解决方案是什么?

在您的sistema.py文件中尝试:

from PyUtils.strings import String

test_sistema.py

import PyUtils.sistema as sis

并确保您的PyUtils目录包含__init__.py文件,这应该解决这个问题。

另一种方法,虽然通常不推荐:在scripts目录下从PyUtils目录导入的任何文件中,从下面开始添加前3行。

toggle_keyboard.py


import sys
from pathlib import Path  
sys.path.insert(0, Path(__file__).parent / "PyUtils")   
from PyUtils.systema as sis
from PyUtils.strings import String
...

PyUtils中的文件可以返回:

from strings import String
import sistema as sis

您仍然希望在PyUtils目录中有__init__.py

另一种方法是捕获导入的异常并尝试替代方法,如....

sistema.py

try:
from strings import String
except ImportError:
from PyUtils.strings import String

test_sistema.py

try:
import sistema.py as sis
except ImportError:
import PyUtils.sistema as sis

在你的情况下,这实际上是更好的选择。

最新更新