pyreverse 在使用绝对导入时不显示 UML 中的组成关系
pyreverse not showing composition relationships in the UMLs when using absolute imports
我在使用 pyreverse
生成 UML 时遇到问题,特别是当 类 不是同一模块的一部分时以及使用绝对导入时的组合关系。
为了说明问题,我在同一个包中有以下两个模块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
两者的组成关系:
但是,当我在 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.py
、a.py
和 b.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 中的模块会导致导入错误。
我在使用 pyreverse
生成 UML 时遇到问题,特别是当 类 不是同一模块的一部分时以及使用绝对导入时的组合关系。
为了说明问题,我在同一个包中有以下两个模块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
两者的组成关系:
但是,当我在 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.py
、a.py
和 b.py
中的几乎您的定义,可以轻松获得所有 classes图表是在单个命令行上使用 pyresverse main.py a.py b.py
。它生成图表:
然而,结果似乎也是
其他实验:包
然后我将 main.py
重命名为 __init__.py
来制作一个包。然后我可以使用 pyreverse 仅提供包的目录名称(或者 . 如果它是当前工作目录)。然后包的所有文件都被处理以制作class图,不需要枚举它们。
在包目录中对包使用 pyreverse 与您的导入语法一起使用,并生成与上述类似的图表。然而,运行 pyreverse 从它的父目录产生 2 个 classes 并排没有关系。这意味着我们正在处理两个不同的 classes B
,其中一个未找到。使用相对导入解决了这个问题。
顺便说一句,我发现添加选项 -m y
以通过添加模块名称来消除 class 名称的歧义很有用:
我可以通过实验验证:每当我取消链接时 classes,从与 pyreverse 相同的当前工作目录启动 python 中的模块会导致导入错误。