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 ClassC and ClassA?
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 makeobject_aan instance variable withself.object_ain the assignment, you can hope to get the result that you expected.Edit: Experimental verification
If the class C is corrected as explained:
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:
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.