【问题标题】:Why does python confuse my packages for modules为什么 python 会混淆我的模块包
【发布时间】:2021-04-06 11:49:22
【问题描述】:

我在根包中有一个包含 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 这样的相对导入来滑冰:从当前包/目录中的一个模块,称为详细信息,导入名为“详细信息”的类。我为程序添加了一些新的(可能是破坏性的)更改,现在,上面相同的相对导入行不再起作用。似乎解释器认为我的包是模块,所以我不能使用绝对导入。

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

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,例如

__package__ = "parsing"
from parsing.details import Details

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

【问题讨论】:

  • "似乎解释器认为我的包是模块,"包是模块。包只是一个包含子模块的模块。这些错误消息将仅涉及模块。您是否已将项目根目录添加到您的路径中?什么是工作目录?在我看来,正确的绝对导入是 clsgn.parsing.details
  • @juanpa.arrivillaga 当您说“您是否已将项目根添加到您的路径中?”你的意思是在导入语句之前使用sys.path.insert(0, "absolute path to my project directory") 或类似的行吗?最好的地方是哪里(每当我需要从我的项目中导入一个类或模块时,这样做似乎有点麻烦)。
  • @juanpa.arrivillaga 我的工作目录也是C:\Users\Ben\VsCode\Python,所以要将项目目录添加到我的系统路径,我应该使用C:\Users\Ben\VsCode\Python 还是C:\Users\Ben\VsCode\Python\clsgn?谢谢
  • 从命令行运行(或从您的 IDE 中运行配置正确设置的等效项)应该这样做 - 您如何运行这些?这是什么%Run
  • @Mr_and_Mrs_D 只是使用解释器调用文件:C://path//to//python//interpreter C://path//to//current//file

标签: python import absolute-path relative-import


【解决方案1】:

在 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 扫描它并找到包类生成器分包解析

【讨论】:

    猜你喜欢
    • 2013-04-18
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    • 2022-07-15
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 2010-09-07
    相关资源
    最近更新 更多