python-3.x 尝试从导入的包导入模块时出现“ModuleNotFoundError”

4xy9mtcn  于 2023-05-08  发布在  Python
关注(0)|答案(6)|浏览(260)

这是我的目录结构:

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中的一个函数。
第一个import(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

g6ll5ycj

g6ll5ycj1#

首先,如果您希望能够从 man1test.py 访问 man1.py,并从 *man1.py * 访问 manModules.py,则需要将文件正确设置为包和模块。

包是一种通过使用“带点的模块名称”来构造Python的模块名称空间的方法。例如,模块名A.B指定名为A的包中名为B的子模块。
...
导入包时,Python会搜索sys.path上的目录,查找包的子目录。
__init__.py文件是使Python将目录视为包含包所必需的;这样做是为了防止具有诸如X1 M5 N1 X的公共名称的目录无意中隐藏稍后在模块搜索路径上出现的有效模块。
你需要把它设置成这样:

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

Second,对于 man1test.py 中的from ...Mans import man1导致的“ModuleNotFoundError: No module named 'Soft'”错误,文档中的解决方案是将 man1.py 添加到sys.path,因为 MansMansTest 包之外。参见Python文档中的模块搜索路径。但是如果你不想直接修改sys.path,你也可以修改PYTHONPATH

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

  • 包含输入脚本的目录(如果未指定文件,则为当前目录)。
  • PYTHONPATH(目录名列表,语法与shell变量PATH相同)。
  • 与安装相关的默认值。
    第三个,对于from ...MansTest.SoftLib import Soft,您说“* 是为了方便www.example.com * 中的上述导入声明man1.py”,这就是导入的工作方式。如果你想在 man1.py 中导入 Soft.SoftLib,你必须设置 man1.py 来找到 Soft.SoftLib 并直接导入。

话虽如此,下面是我如何让它工作的。
man1.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())

man1test.py

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

man1.foo()

manModules.py

def module1():
    return "module1 in manModules"

端子输出:

$ python3 -m man.MansTest.Unittests.man1test
Traceback (most recent call last):
  ...
    from ...Mans import man1
  File "/temp/man/Mans/man1.py", line 2, in <module>
    from Soft.SoftWork.manModules import *
ModuleNotFoundError: No module named 'Soft'

$ PYTHONPATH=$PYTHONPATH:/temp/man/MansTest/SoftLib
$ export PYTHONPATH
$ echo $PYTHONPATH
:/temp/man/MansTest/SoftLib
$ python3 -m man.MansTest.Unittests.man1test
called foo in man1.py
foo called module1 from manModules: module1 in manModules

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

2g32fytz

2g32fytz2#

我也有类似的问题,虽然不一样。
我的文件夹和文件的结构(GUI_ML是主文件夹):

GUI_ML
\ Views \ login.py
\ Views \ __ init __.py
\ Controllers \ Control_login.py
\ Controllers \ __ init __.py

我需要从login.py导入Control_login.py。下面的代码解决了我的问题:

import sys
import os
myDir = os.getcwd()
sys.path.append(myDir)

from pathlib import Path
path = Path(myDir)
a=str(path.parent.absolute())

sys.path.append(a)

from Controllers.Control_login import Control_login
qxsslcnc

qxsslcnc3#

对于我来说,当我创建一个文件并将其保存为python文件时,我在导入过程中遇到了这个错误。我必须创建一个类型为“.py”的文件名,比如filename.py,然后将其保存为python文件。尝试导入文件的帖子为我工作。

z9smfwbn

z9smfwbn4#

某些包名和模块名可能相同。该冲突也以该错误来响应。

ep6jt1vc

ep6jt1vc5#

我也遇到了类似的问题,我忘记在模块中放一个__init__.py,花了很多时间来试图理解哪里出了问题。

w51jfk4q

w51jfk4q6#

另一种解决方案取决于您从何处运行此代码。
假设OP的目录结构:

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

如果您尝试运行python Mans/man1.py(从man目录),则必须执行以下两项操作才能使其正常工作:
1.将www.example.com中的导入行更改man1.py为from ManTest.SoftLib.Soft.SoftWork.manModules import *
1.如果还没有,请添加到系统环境变量。键PYTHONPATH,值.

相关问题