Python:尝试从已导入的程序包中导入模块时发生“ ModuleNotFoundError”问题

时间:2019-02-08 18:29:13

标签: python python-3.x python-import

我在macOS Mojave版本10.14.1上使用Python 3.7.1

这是我的目录结构:

man/                          
  Mans/                  
          man1.py
  MansTest/
          SoftLib/
                  Soft/
                      SoftWork/
                              manModules.py
          Unittests/
                    man1test.py

man1.py包含以下 import 语句,我不想更改

from Soft.SoftWork.manModules import *

man1test.py包含以下 import 语句:

from ...MansTest.SoftLib import Soft
from ...Mans import man1

我需要在man1test.py中进行第二次 import ,因为man1test.py需要访问man1.py中的函数。

我第一次导入( Soft )的理由是促进man1.py中的上述 import 语句。

与我的预期相反,但是man1.py中的 import 语句引起了:

ModuleNotFoundError: No module named 'Soft'

我跑步时

python3 -m man.MansTest.Unittests.man1test

来自 man / 上方的目录。

有什么方法可以解决此错误,而无需更改man1.py 中的 import 语句,而无需在 sys.path ?

编辑:将问题的原始版本python3 -m man.ManTest.Unittests.man1test更改为python3 -m man.MansTest.Unittests.man1test

3 个答案:

答案 0 :(得分:1)

您的设置有几个令人困惑的要求,但我会尽力为您提供所需的内容。

第一,如果您希望能够从 man1test.py manModules.py访问 man1.py man1.py 中的em>,则需要将文件正确设置为packages and modules

  

包是一种通过使用来构造Python模块名称空间的方法   “点缀的模块名称”。例如,模块名称2指定一个   名为=DAYMONL(6;10;2019) =DAYMONL(3;4;1999) 的程序包中名为A.B的子模块。

     

...

     

在导入软件包时,Python在以下目录中搜索   B查找包子目录。

     

需要A文件来使Python处理   目录包含软件包;这样做是为了防止   具有常见名称(例如sys.path)的目录   隐藏在模块搜索路径上稍后出现的有效模块。

您需要将其设置为以下内容:

__init__.py

SECOND ,对于由 man1test.py 中的string引起的“ man |- __init__.py |- Mans |- __init__.py |- man1.py |- MansTest |- __init.__.py |- SoftLib |- Soft |- __init__.py |- SoftWork |- __init__.py |- manModules.py |- Unittests |- __init__.py |- man1test.py 错误,针对此问题的解决方案是添加< em> man1.py ModuleNotFoundError: No module named 'Soft',因为 Mans MansTest 包之外。请参阅Python文档中的The Module Search Path。但是,如果您不想直接修改from ...Mans import man1,也可以修改sys.path

  

sys.path从以下位置初始化:

     
      
  • 包含输入脚本的目录(如果未指定文件,则为当前目录)。
  •   
  • PYTHONPATH(目录名称列表,语法与shell变量sys.path相同)。
  •   
  • 与安装有关的默认设置。
  •   

THIRD ,对于PYTHONPATH,您说“ 是为了促进man1.py 中的上述import语句”,这就是导入的工作方式。如果要在 man1.py 中导入 Soft.SoftLib ,则必须设置 man1.py 来找到 Soft.SoftLib < / em>并将其直接导入那里。

话虽如此,这就是我如何使其工作。

man1.py:

PATH

man1test.py

from ...MansTest.SoftLib import Soft

manModules.py

from Soft.SoftWork.manModules import *
# no change to import statement but need to add Soft to PYTHONPATH

def foo():
    print("called foo in man1.py")
    print("foo call module1 from manModules: " + module1())

端子输出:

# no need for "from ...MansTest.SoftLib import Soft" to facilitate importing..
from ...Mans import man1

man1.foo()

作为建议,也许可以重新考虑那些 SoftLib 文件的用途。是 man1.py man1test.py 之间的某种“桥梁”吗?现在设置文件的方式,我认为它不会像您期望的那样起作用。另外,被测代码( man1.py )从测试文件夹( MansTest )导入内容也有些令人困惑。

答案 1 :(得分:0)

对我来说,当我创建一个文件并将其另存为python文件时,我在导入期间遇到此错误。 我必须创建一个类型为“ .py”的文件名,例如filename.py,然后将其另存为python文件。 尝试导入文件的帖子对我有用。

答案 2 :(得分:-2)

这是我重命名模块时发生的事情,即使所有内容都一直被重构。将模块重命名为其他名称可以解决此问题。我不确定为什么。