pyreverse is a great tool to generate UML diagram from Python codes. However, I found it cannot identify all the classes that has been used within a function. I take the following example to illustrate my point:
class ClassA(object): def __init__(self): pass class ClassB(object): def __init__(self): pass class ClassC(object): def __init__(self): self.object_b = ClassB() def perform(): object_a = ClassA()
If we use pyreverse to generate class diagram, it is clear that we can see
ClassB is a component within
ClassC. However, it cannot generate the relationship with
ClassA, which is used in its function
perform. Is there any way for pyreverse to retrieve the relationship between
The reason is the scope of
object_a: it is a local variable of the function and not an instance variable. The relationship of C with A is therefore not structural. Hence, it is not an UML association (nor aggregation, nor composition).
At best, we could say there is a usage dependency from C to A. But this usage is specific to the implementation and not necessarily meant by design.
I’m not a Python expert, but if pyreverse is able to spot the right relation with
object_b, and if you’d make
object_a an instance variable with
self.object_a in the assignment, you can hope to get the result that you expected.
Edit: Experimental verification
If the class C is corrected as explained:
class ClassC(object): def __init__(self): self.object_b = ClassB() def perform(self): self.object_a = ClassA()
pyreverse generates indeed the right result as expected:
For a human reader, it’s easy to miss a property. This is why pylint issues a warning on this code:
W0201: Attribute 'object_a' defined outside __init__ (attribute-defined-outside-init)
Note also that if you define a (static) class variable instead of an instance variable, pyreverse does not show it with an underlined name. The reason is probably, because it’s not uncommon to hide a class variable with an instance variable of the same name.