3

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

为了说明这个问题,我有以下两个模块a.py并且b.py在同一个包中:

a.py

from b import B


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

b.py

class B:
    pass

当我从包的终端中运行pyreverse命令时,我得到以下 UML。它没有显示两个类A和之间的组合关系B

在此处输入图像描述

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

在此处输入图像描述

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

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

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

4

1 回答 1

2

在额外的实验之后编辑的答案

我不是 python 专家,但经过几次实验,我想我得到了你需要的信息

第一次实验:无包装

在我的第一个实验中,我使用了几个不在一个包中的模块。当使用不同的方式进行导入时,pyreverse 只显示命令行中提到的模块的类。

虽然我最初认为这个问题与更严格的导入语法有关,但事实证明它只是按照手册页中的设计和记录工作:pyreverse 在图中仅显示 pyreverse 命令行中列出的模块的类.

因此,在一个小项目中,几乎使用了您在 files 中的定义 main.pya.py并且b.py获取图中所有类的简单解决方法是pyresverse main.py a.py b.py在单个命令行上使用。它生成图表:

在此处输入图像描述

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

附加实验:包

然后我重命名main.py__init__.py做一个包。然后我可以使用 pyreverse 只提供包的目录名称(或者 . 如果它是当前工作目录)。然后处理包的所有文件以制作类图,无需枚举它们。

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

我发现-m y通过添加模块名称来添加选项以消除类名的歧义很有用:

在此处输入图像描述

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

于 2022-02-11T00:55:41.837 回答