为什么python将我的包混淆为模块

问题描述

我在根包中有一个包含 3 个嵌套包的项目

clsgen 
-__init__.py
-main.py
-parsing
    -__init__.py
    - class1.py
    - class2.py
-generator
    -__init__.py
    -some_class_files
    -...
-utils
    -__init__.py
    -some_modules
    -...

在导入和使用包时,我遇到了很多困难(通常使用 python - 可能是 Java/Eclipse 在我的选项中做的唯一正确的事情)。最近,我可以通过使用诸如 from .details import Details 之类的相对导入来滑行:从当前包/目录中的一个名为 details 的模块中,导入名为“Details”的类。我已经向程序添加了一些新的(可能是破坏性的)更改,现在,上面相同的相对导入行不再有效。似乎解释器认为我的包是模块,所以我不能使用绝对导入。

例如,如果我将导入更改为:

from parsing.details import Details

我收到此错误

>>> %run class_dict.py
Traceback (most recent call last):
  File "C:\Users\Ben\VsCode\python\classgenerator\parsing\class_dict.py",line 12,in <module>
    from parsing.details import Details
  File "C:\Users\Ben\AppData\Local\Programs\Thonny\lib\site-packages\thonny\backend.py",line 305,in _custom_import
    module = self._original_import(*args,**kw)
ModuleNotFoundError: No module named 'parsing'

我什至尝试根据需要覆盖内置的,例如

__package__ = "parsing"
from parsing.details import Details

我非常有信心我的项目打包结构设置正确(如上面的第一个示例所示(但更详细))。而且我也非常有信心我理解包、模块、相对与绝对导入的概念。然而,每当我尝试使用 Python 制作多包程序时,这个问题都会困扰着我。我真的很感激有人指出错误或建议我可以采取哪些措施来缓解这个持续存在的问题。

解决方法

在 Java 中,导入只是语法糖(不是真的)。在 python 中,它们是实际语句,它们根据涉及 sys.path 变量和当前工作目录的复杂规则进行解析。运行驻留在包中的 python 脚本(又名模块)的正确方法是:

$ C://path//to//python//interpreter.exe -m packagename.modulename

所以你的情况

$ cd "C:\Users\Ben\VsCode\python\"
$ C://path//to//python//interpreter.exe -m classgenerator.parsing.class_dict

这样相对导入被正确解析,因为“C:\Users\Ben\VsCode\python”被自动添加到 sys.path 并且 python 扫描它找到包类生成器子包解析