[Python] 파이썬 UML Diagram 자동 생성

hwhyeons·2023년 12월 2일

파이썬으로 간단한 프로젝트로 시작했지만 점점 클래스 단위가 복잡해지다보니

다이어그램의 필요성을 느꼈다.

원래는 drawio로 그렸는데, 설계를 미리 해놨다가 설계를 수정할 떄마다

함수명이며 변수명이며 계층 구조 다 수정하는 것이 너무 힘들다보니

오히려 설계 없이 마구잡이로 작성하게 되니 나중에 다시 볼 때 문제가 많이 발생하였다.




그래서 자동으로 다이어그램을 생성해주는 도구가 없을까 찾아보았다.

나는 Python 프로젝트는 Pycharm을 이용해서 주로 작업을 한다.

Pycharm Professional의 경우 자체 다이어그램 기능을 제공하는 것 같다 (링크)


나는 무료버전이므로 다른 방법을 찾던 중에 graphviz와 pylint를 이용해서

다이어그램을 자동 생성하는 방식을 발견해서 사용해보았다.



파이참을 사용할 때 보통 프로젝트마다 가상환경을 만들어서 사용하기 때문에

pip를 통해 설치했다.

pip install pylint
pip install graphviz

설치가 완료되면, 프로젝트에 py파일을 하나 만들어서 테스트해보자.

test_diagram.py파일을 만들고

global_var = 10

def func():
    pass

이렇게 작성하고

pyreverse -o png test_diagram.py

터미널에서 실행해주면

classess.png 파일이 생성되는데, 이미지 파일을 열어보면 아무것도 나타나지 않는다.

클래스 다이어그램을 그려주기 때문에 클래스가 없이 전역 변수나 함수는

그림에 포함되지 않았다.


test_diagram.py에 class를 추가해주었다.

class TestClass:
    def __init__(self):
        self.member = 10

이후 터미널에서 같은 명령어를 실행하고 png파일을 열어보면


이렇게 자동으로 그려진 것을 볼 수 있다.

TypeHint 없이도 타입추론이 가능하다면 자동으로 타입까지 지정해준다.



클래스 다이어그램이기 때문에 연관이나 참조 등의 관계가

표현되는 것이 가장 필요하다.

py파일을

class NewClass:
    pass

class TestClass:
    def __init__(self):
        self.member: int = 10
        self.new_inst = NewClass()

이렇게 바꿔주고 생성해보면

잘 나온다.




패키지 단위로 생성

방금은 py 파일 하나로 생성했지만, 당연히 프로젝트 규모가 커지면

파일 하나가 아닐 것이다.

패키지로 이미지를 생성하려면 원하는 패키지에

__init__.py

파일을 만들어야 한다.

터미널에서 cd 명령어로 uml_test 폴더로 이동 후에,

pyreverse -o png ./

를 실행해주었다. ./은 현재 디렉터리 경로를 의미한다.

각 파일의 코드는 아래에 적어두었다.

# test.py
from uml_test.inner_package.A import ClassA

class ClassB(object):
    def __init__(self):
        self.object_c = ClassC()

class ClassC(object):
    def __init__(self):
        self.object_b = ClassB()
        self.object_a = ClassA()

# test_diagram.py
class NewClass:
    pass

class TestClass:
    def __init__(self):
        self.member: int = 10
        self.new_inst = NewClass()

# A.py
class ClassA(object):
    def __init__(self):
        self.hi = 10

이렇게 구조를 만들어놓고 다이어그램을 생성하면

자동으로 잘 생성 되는 것을 확인할 수 있다.


만약에 패키지가 다른 py파일에서 참조 관계가 다이어그램에 반영이 안된다면

__init.py__ 에서

from uml_test.inner_package.A import ClassA

을 넣어주고

다른 패키지에도 (위 예시에서는 inner_package폴더)
__init.py__
를 만들어준다.

0개의 댓글