pyreverse 在使用绝对导入时不显示 UML 中的组成关系

pyreverse not showing composition relationships in the UMLs when using absolute imports

我在使用 pyreverse 生成 UML 时遇到问题,特别是当 类 不是同一模块的一部分时以及使用绝对导入时的组合关系。

为了说明问题,我在同一个包中有以下两个模块a.pyb.py

a.py:

from b import B


class A:
    def __init__(self, b):
        self.b: B = b

b.py:

class B:
    pass

当我从程序包中在终端中 运行 pyreverse 命令时,我得到以下 UML。不显示类AB两者的组成关系:

但是,当我在 a.py 中执行相对导入 from .b import B 时,我得到了预期的结果:

似乎 pyreverse 在第一种情况下不承认 类 B 是相同的。为了解决这个问题,我尝试将包的绝对路径添加到环境变量PYTHONPATH。但是,这并没有解决问题。

有谁知道当 类 在不同模块中定义并且使用绝对导入时,我如何使 pyreverse 在 UML 中生成正确的关系?

我正在使用 python 3.8.8 和 pylint 版本 2.12.2。

经过额外实验后编辑的答案

我不是 python 专家,但经过更多实验后,我想我得到了您需要的信息

第一次实验:没有包

在我的第一个实验中,我使用了几个不在一个包中的模块。当使用不同的方式执行 imports 时,pyreverse 仅显示命令行中提到的模块的 classes。

虽然我最初认为该问题与更严格的导入语法有关,但事实证明,实际上它只是按照 man page 中设计和记录的方式工作:pyreverse 在图表中仅显示 classes of the modules listed in the pyreverse command line.

因此,通过一个小项目,使用文件 main.pya.pyb.py 中的几乎您的定义,可以轻松获得所有 classes图表是在单个命令行上使用 pyresverse main.py a.py b.py。它生成图表:

然而,结果似乎也是 ,您调用 pyreverse 的当前目录和用于指定模块的路径,因为这些元素会影响正确导入的查找。

其他实验:包

然后我将 main.py 重命名为 __init__.py 来制作一个包。然后我可以使用 pyreverse 仅提供包的目录名称(或者 . 如果它是当前工作目录)。然后包的所有文件都被处理以制作class图,不需要枚举它们。

在包目录中对包使用 pyreverse 与您的导入语法一起使用,并生成与上述类似的图表。然而,运行 pyreverse 从它的父目录产生 2 个 classes 并排没有关系。这意味着我们正在处理两个不同的 classes B,其中一个未找到。使用相对导入解决了这个问题。

顺便说一句,我发现添加选项 -m y 以通过添加模块名称来消除 class 名称的歧义很有用:

我可以通过实验验证:每当我取消链接时 classes,从与 pyreverse 相同的当前工作目录启动 python 中的模块会导致导入错误。