【问题标题】:Package Pathing Errors in PythonPython 中的包路径错误
【发布时间】:2018-05-28 23:31:09
【问题描述】:

所以我正在为我的 Python 实现一个文件结构,并且在执行导入时出错。文件结构如下所示:

Dirs(Folder)
   ╘ run.py
     Vers(Folder)
        ╘ __init__.py
          1_1(Folder)
             ╘ Main.py
               secondary.py
               __init__.py
          1_2(Folder)
             ╘ Main.py
               secondary.py
               __init__.py

这是run.py的内容

import importlib
print("This is the main module")
A = importlib.import_module(str("Vers.1_1.Main"))
A.start()
B = importlib.import_module(str("Vers.1_2.Main"))
B.start()

每个Main.pysecondary.py 都包含相同的代码,只是打印语句中的版本号会根据它们所在文件夹的版本号而改变。

Main.py

import secondary
class start():
    def __init__(self):
        print("This is version 1.2 main")
        secondary.start()

secondary.py

class start():
    def __init__(self):
        print("This is version 1.1 secondary")

这是我执行run.py时得到的输出

This is the main module
Traceback (most recent call last):
  File "Python\Python36-32\lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 978, in _gcd_import
  File "<frozen importlib._bootstrap>", line 961, in _find_and_load
  File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
  File "Dirs\Vers\1_1\Main.py", line 1, in <module>
import secondary
ModuleNotFoundError: No module named 'secondary'

所以据我了解,run.py 能够成功找到并尝试从1_1 文件夹中导入Main.py。但是,在执行Main.py文件时,无法看到secondary.py在同一个目录下导入。我试过寻找如何解决这个问题,但我真的不知道我的问题是什么。我尝试设置软件包的方式是错误的吗?如果是这样,我需要进行哪些更改才能使其正常工作?

【问题讨论】:

    标签: python packages python-import


    【解决方案1】:

    简答:使用

    from . import secondary
    

    更长的版本:看起来您假设 Python 2 相对导入 语义,而这是具有 绝对导入 语义的 Python 3。看看例如here获取更详细的解释。

    如果你这样做

    import secondary
    

    这是一个绝对导入,因此不是相对于当前包解析,而是从sys.path解析。

    当您将 run.py 作为 Python 脚本(而不是作为带有 -m 的模块)执行时,脚本所在的目录会自动添加到 sys.path,这就是导入 Vers.1_1.Main 有效的原因,但 @987654329 @ 没有。

    【讨论】:

    • 非常感谢。这可能是我最好的解决方案,因为我不想每次都修改所有导入语句,因为我很棒的新版本目录:P
    • @Skitzafreak ...这正是为什么有那些不错的显式相对导入的原因之一 ;-)。
    • 一个问题。假设我有一个像from Mod import ClassA 这样的导入。我如何将其更改为 from . import 符号? from . import Mod.ClassA 有效吗?
    • @Skitzafreak from .Mod import ClassAfrom ... import 只允许您直接导入子模块,而不是作为子模块(除非外部模块为您这样做)。
    【解决方案2】:

    导入后,您的代码在Dirs 下执行,没有要导入的辅助模块

    改变

    import secondary
    

    Main.py

    import Vers.1_1.secondary
    

    import Vers.1_2.secondary
    

    在另一个Main.py

    【讨论】:

      猜你喜欢
      • 2016-11-24
      • 2012-10-08
      • 1970-01-01
      • 1970-01-01
      • 2015-12-16
      • 2016-04-13
      • 2020-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多