한컴테크를 통해 한컴의 기술을 공유합니다. 한컴의 프로그래밍, 프레임워크, 라이브러리 및 도구 등 다양한 기술을 만나보세요. 한컴 개발자들의 다양한 지식을 회사라는 울타리를 넘어 여러분과 공유합니다. 한컴이 제공하는 기술블로그에서 새로운 아이디어와 도전을 마주하고, 개발자가 꿈꾸는 미래를 실현하세요.

한컴테크

Python의 시작, 그리고 개발 환경 세팅과 관리

이미지 출처 – 파이썬 로고 (https://www.python.org/ )

시작하며…


이번 글에서는 파이썬 언어를 사용하여, 개발하고 동료 개발자들과의 협업할 때 유용한 도구들을 소개하려 합니다.

해당 글은 주니어 개발자 및 타 프로그래밍 언어는 익숙하지만 파이썬 언어는 많이 다뤄보지 않은 분들에게 초점을 맞춰서 작성되었다는 점 참고 부탁드립니다.

  • 저는 2018년 한글과컴퓨터에 입사하고 나서 처음으로 파이썬 언어를 다루고 사용하기 시작했습니다. 미천한 경험이 전부이기 때문에 해당 글을 작성하는 저 또한 파이썬 언어를 잘 알고, 다루는 개발자가 아니라는 점 알려드립니다. 그동안의 파이썬 언어를 사용한 경험을 토대로 글을 작성해 보았으니 많은 양해 부탁드립니다.

왜 파이썬인가?


파이썬 언어의 가장 큰 특징으로는 위 문구에서 보다시피, 직관적이고 문법이 단순하여 아름다우며 생산성이 매우 빠릅니다. 이런 특징을 Pythonic하다고도 합니다.

Pythonic 한 특징 덕분에 주니어 개발자들이 쉽게 배울 수 있어 프로그래밍을 입문할 때 많이 추천하는 언어입니다.

주니어 개발자들이 쉽게 사용할 수 있는 언어라고 해서 사용률과 생산성이 떨어지는 것은 아닙니다.

  • 전 세계 많은 분들이 사용하고 있는 Instagram은 파이썬 웹 프레임워크 중 하나인 Django(https://www.djangoproject.com) 프레임워크로 개발되었습니다.
  • 또한, TIOBE 인덱스(https://www.tiobe.com/tiobe-index)를 확인해 보면 작성일 기준으로 여전히 프로그래밍 언어 순위 1등을 차지하고 있어, 가장 인기가 많은 프로그래밍 언어라고 할 수 있습니다.
  • 최근 AI 커뮤니티 중 Hugging Face(https://huggingface.co) 주목과 인기로 인해, 모델 및 도구를 사용하기 위해서 파이썬 언어에 대해 이해가 필요해지고 있습니다.

이렇게 파이썬 언어는 풍부한 라이브러리들을 바탕으로 한 강력한 파이썬 언어만의 생태계를 가지고 있어 다양한 개발 분야에서 널리 사용되고 있습니다.

지금부터 파이썬 언어를 이용하여 개발할 때, 사용하면 유용한 도구들을 소개해 드리겠습니다.

1. 가상환경 생성 및 사용

파이썬 언어는 virtualenv, conda 등을 통한 가상환경을 독립적으로 구성하여 사용할 수 있습니다.

  • virtualenv, conda를 통한 가상환경의 구성 예시
# virtualenv 명령어를 통한 가상환경 생성 및 활성화
$ python -m virtualenv .venv
$ source .venv/bin/activate
# 비활성화
$ deactivate
# conda를 사용한 가상환경 생성 및 활성화
$ conda create -n venv python=3.8.10
$ conda activate venv
# 비활성화
$ conda deactivate
  • conda 유료화 정책으로 인해, miniconda & conda-forge 설정을 통한 우회 사용을 권장 드립니다.
$ conda config --add channels conda-forge
$ conda config --set channel_priority strict
# Anaconda Repository 삭제
$ conda config --remove channels defaults
$ conda config --show channels
channels:
  - defaults(변경 전)
  - conda-forge(변경 후)

가상환경을 독립적으로 구성하여, 개발했을 때의 장점

  1. 의존성 관리
    각 프로젝트마다 필요한 패키지와 버전이 다를 수 있기 때문에 가상환경을 사용하면 각 프로젝트마다 독립적인 환경을 만들어 필요한 패키지를 설치할 수 있습니다. 이렇게 하면 서로 다른 프로젝트 간의 패키지 충돌을 피할 수 있습니다.
  2. Host 시스템 환경과 격리
    Host 시스템에 이미 설치된 패키지나 버전이 프로젝트에 필요한 패키지나 버전과 다를 수 있습니다. 가상환경을 사용하면 프로젝트에 필요한 환경을 격리시켜, Host 시스템 환경에 영향을 미치지 않고 이를 통해 개발 환경과 Host 시스템 환경 간의 일관성을 유지할 수 있습니다.
  3. 프로젝트 이식성 향상
    가상환경을 사용하여 개발한 프로젝트는 다른 환경에서도 쉽게 이식할 수 있습니다. 또한 다른 개발자나 서버와 프로젝트를 공유할 때 프로젝트의 가상환경을 함께 제공하여 프로젝트를 쉽게 실행하고 관리할 수 있습니다.
  4. 개발자 독립성 보장
    여러 개발자가 동일한 프로젝트를 협업할 때 각자의 개발 환경을 가상환경으로 구성하여 개발할 수 있습니다. 이를 통해 각 개발자가 자신의 환경에서 프로젝트를 독립적으로 개발할 수 있으며, 서로의 환경에 영향을 주지 않을 수 있습니다.
  5. 패키지 버전 관리
    가상 환경을 사용하면 프로젝트의 패키지 버전을 관리할 수 있습니다. 필요에 따라 특정 버전의 패키지를 사용하거나 업그레이드하는 것이 가능하며, 이를 통해 프로젝트의 안정성과 성능을 개선할 수 있습니다.

2. 효율적인 패키지 관리

파이썬 언어로 개발을 진행하다 보면, 타 프로그래밍 언어에서 라이브러리를 관리하는 것과 달리 프로젝트 단위 내 설치된 패키지의 의존성 관리가 힘들고 취약하다고 많이 느끼셨을 겁니다.

파이썬 가상환경에 설치된 패키지 목록을 requirements.txt 파일 하나로 관리하기 때문에 거대 프로젝트가 되었을 때, 패키지 간의 물고 물리는 의존성 관계가 형성되면 패키지 관리가 어렵게 됩니다.

파이썬 언어의 풍부한 라이브러리 생태계 덕분에 하나의 프로젝트가 거대해질 수 있지만 이로 인해 설치된 라이브러리 구조가 대략 아래와 같이 복잡한 수준을 넘어서 거미줄처럼 변모하게 됩니다.

이미지 출처 – ResearchGate
(https://www.researchgate.net/figure/Figure-E5-The-dependencies-of-python-packages-on-one-of-the-authors-machines-in-2019_fig3_335564976 )

이때 특정 라이브러리를 설치하여, 사용한 뒤 필요가 없어진 경우에 삭제를 하거나 라이브러리의 버전을 변경하는 등의 행동을 했을 때에는 의존 관계에 묶여 있는 라이브러리로 인해 프로젝트의 라이브러리 관계가 꼬이게 되어 관리가 어렵게 됩니다.

파이썬 언어가 패키지 관리에 취약하다는 점을 앞에서 언급한 파이썬 가상환경에 하나의 라이브러리를 설치 후, 해당 라이브러리를 삭제하는 일련의 과정을 통해 보여드리겠습니다.

# install requests. Requests is a simple, yet elegant, HTTP library.
$ pip install requests
Installing collected packages: urllib3, idna, charset-normalizer, certifi, requests
Successfully installed certifi-2024.2.2 charset-normalizer-3.3.2 idna-3.6 requests-2.31.0 urllib3-2.2.1
$ pip list
Package            Version
------------------ --------
certifi            2024.2.2
charset-normalizer 3.3.2   
idna               3.6     
pip                24.0    
requests           2.31.0  
setuptools         69.0.3  
urllib3            2.2.1   
wheel              0.42.0

requests 라이브러리를 설치 시, 해당 라이브러리를 사용하기 위한 라이브러리들이 함께 설치된 것을 볼 수 있습니다. 그렇다면 해당 라이브러리의 사용이 더 이상 필요하지 않은 경우, 삭제를 했을 때는 어떻게 되는지 확인해 보겠습니다.

$ pip uninstall 
Proceed (Y/n)? y
  Successfully uninstalled requests-2.31.0
$ pip list
Package            Version
------------------ --------
certifi            2024.2.2
charset-normalizer 3.3.2
idna               3.6
pip                24.0
setuptools         69.0.3
urllib3            2.2.1
wheel              0.42.0

해당 라이브러리는 삭제가 되었지만, requests 라이브러리를 사용하기 위해 함께 설치되었던 라이브러리들은 그대로 남아 있는 것을 볼 수 있습니다. 프로젝트에서 더 이상은 사용하지 않지만, 미처 지우지 못하고 그대로 남아있는 라이브러리로 인해 추후에 큰 문제가 발생할 수 있습니다.

  • 개발 과정에서 사용하고, 미처 정리하지 않은 라이브러리들이 함께 배포되는 과정에서 라이선스 문제 발생한다면 큰 문제를 불러올 수 있습니다.
A라는 라이브러리 사용을 위해 함께 설치된 의존성 패키지의 모습
더 이상 필요가 없어, C라는 패키지를 삭제했지만, 함께 설치된 D, E, F 패키지는 그대로 방치(?) 되어 문제가 될 여지가 있는 모습

이러한 파이썬 패키지들의 의존성 및 복잡성을 해결하고 효율적으로 패키지를 관리할 수 있는 Poetry(https://python-poetry.org)라는 도구를 소개해 드립니다.

본격적으로 Poetry를 설치하여 사용해 보도록 하겠습니다.

# poetry 설치
$ curl -sSL https://install.python-poetry.org | python3 -
# poetry 프로젝트 생성
$ poetry new test-project
# 생성한 프로젝트에서 초기화 진행 및 프로젝트 정보 입력
$ poetry init

그럼 이제 Poetry를 이용하여 requests 설치 후 삭제하는 과정을 진행해 보도록 하겠습니다.

# 라이브러리 설치 및 의존성 대상 설정
$ poetry add requests
Using version ^2.31.0 for requests
Updating dependencies
Resolving dependencies... (0.7s)
Package operations: 5 installs, 0 updates, 0 removals
  - Installing certifi (2024.2.2)
  - Installing charset-normalizer (3.3.2)
  - Installing idna (3.6)
  - Installing urllib3 (2.2.1)
  - Installing requests (2.31.0)
Writing lock file
# 설정한 라이브러리의 의존성 관계 확인
$ poetry show --tree
requests 2.31.0 Python HTTP for Humans.
├── certifi >=2017.4.17
├── charset-normalizer >=2,<4
├── idna >=2.5,<4
└── urllib3 >=1.21.1,<3
# 라이브러리 삭제 및 의존성 관리 대상 설정 삭제
$ poetry remove requests
Updating dependencies
Resolving dependencies... (0.1s)
Package operations: 0 installs, 0 updates, 5 removals
  - Removing certifi (2024.2.2)                    
  - Removing charset-normalizer (3.3.2)
  - Removing idna (3.6)                   
  - Removing requests (2.31.0)          
  - Removing urllib3 (2.2.1)
Writing lock file

.toml 파일 내 [tool.poetry.dependencies] 아래 작성된 의존성 라이브러리 관리 대상에 따라, 해당 라이브러리의 의존성 패키지들도 함께 삭제되는 것을 확인할 수 있습니다.

Poetry 사용 이점

  1. 의존성 관리
    Poetry는 프로젝트의 의존성을 관리하는 데에 용이합니다. Dependency Resolver로 복잡한 라이브러리 간의 버전 충돌을 방지하고 의존성을 프로젝트 내의 pyproject.toml 파일에 명시하고 관리함으로써 다른 개발자들과 프로젝트를 공유할 때 일관성을 유지할 수 있습니다.
  2. 가상 환경 관리
    Poetry는 프로젝트마다 독립적인 가상 환경을 생성하여, 이를 통해 프로젝트 간의 의존성 충돌을 방지하고 프로젝트를 더 격리된 환경에서 실행할 수 있습니다.
  3. 프로젝트 버전 관리
    Python 버전 및 프로젝트의 버전을 관리할 수 있습니다. 프로젝트를 배포할 때 다양한 버전의 Python 패키지를 생성 및 자동으로 업데이트하고, 의존성이 업데이트되었을 때 버전을 자동으로 갱신할 수 있습니다.
  4. 배포 및 패키지 관리
    프로젝트를 배포하기 위한 명령어를 제공하며, PyPI와 같은 패키지 저장소와의 통합을 제공합니다. 이를 통해 프로젝트의 패키지 관리를 보다 효율적으로 할 수 있습니다.

3. 동적 타입 언어의 보완

파이썬 언어는 앞에서 이야기한 것처럼 Pythonic 한 특징인 동적 타입 언어로 실행 시에 데이터 타입을 결정합니다. 따라서, 생산성은 높을지언정 안정성은 정적 타입 언어에 비해 떨어지게 되고 하나의 변수에 대해서 데이터 타입이 뒤죽박죽 섞일 우려가 있습니다. 오랫동안 정적 타입 언어를 이용하신 개발자의 경우에는 불편할 수 있는 특징이기도 합니다.

동적 타입 언어를 다룰 때 발생할 수 있는 취약점 예시를 하나 소개해 드리겠습니다.

a라는 변수를 선언하고, 다른 데이터 타입을 재할당 하는 예시입니다. a라는 변수에 int형 타입 힌팅은 사실상 소용이 없고, 에러 또한 발생하지 않으며 정상 동작을 합니다.

a: int = 1
print(type(a))
# <class 'int'>
a = '1'
print(type(a))
# <class 'str'>

이러한 Pythonic 한 특징이자, 취약점으로 보일 수 있는 특징을 보완하기 위한 Mypy(https://mypy.readthedocs.io/en/stable) 라이브러리를 소개해 드리겠습니다. Mypy는 Python의 정적 타입 검사 도구 중 하나로, 코드를 실행하기 전에 타입 오류를 찾아내는 데 사용됩니다.

Mypy는 가장 널리 사용되고 있는 파이썬 정적 타입 검사 도구입니다. Mypy 타입 검사기는 코드에서 변수와 함수를 올바르게 사용하고 있는지 확인하는 데에 도움을 줍니다. 앞에서 말씀드린 것처럼 파이썬은 동적 언어이므로 실행할 때 코드에 오류가 표시되지만, 정적 검사기인 Mypy를 이용하면 프로그램을 실행하지 않고도 데이터 타입에 대한 오류를 발견할 수 있습니다.

이미지 출처 – https://star-history.com/
파이썬 타입 체킹 라이브러리별 히스토리 및 stars 비교

그럼 Mypy를 설치하여, 방금 전 코드를 검사해 보도록 하겠습니다.

# mypy 설치
$ pip install mypy
# mypy 설치 확인
$ mypy --version
mypy 1.9.0 (compiled: yes)
# mypy 정적 검사기 실행
$ mypy mypy_test.py
mypy_test.py:4: error: Incompatible types in assignment (expression has type "str", variable has type "int")  [assignment]
Found 1 error in 1 file (checked 1 source file)

최초에 선언한 a라는 변수에 대해서 데이터 타입에 대한 검사 결과를 확인해 주었습니다. 변수 외에도 함수 매개변수, 반환 값 등에 적용 가능하기 때문에 타입 힌팅을 충분히 활용한다면 코드 전반에 걸쳐서 검사를 확인할 수 있습니다.

이를 이용하면 굳이 실행을 하지 않더라도, 코드 내(코드의 작성자가 본인이 아닌 동료의 코드를 보더라도)에 존재하는 각각의 데이터 타입에 대해서 확인할 수 있을 것입니다.

Mypy는 점진적인 타이핑을 염두에 두고 설계되었기 때문에 코드 베이스에 유형 힌트를 천천히 추가할 수 있으며 정적 유형 지정(타입 힌팅)이 편리하지 않은 경우, 언제든지 동적 유형 지정으로 돌아갈 수 있습니다. 따라서 타입 검사가 필요한 경우와 필요하지 않은 경우를 나눠서 코드를 작성할 수 있습니다.

또한, 사용자는 mypy.ini 파일 설정을 통해 Mypy와 관련된 옵션을 상황에 따라 자유롭게 사용할 수 있습니다.

# mypy.ini
[mypy]
strict = True
ignore_missing_imports = True
show_error_codes = True
pretty = True

Mypy 라이브러리 사용의 이점

  1. 타입 안정성 향상
    정적 타입 검사를 통해 코드의 타입 오류를 미리 찾아낼 수 있습니다. 이는 실행 중에 발생할 수 있는 예기치 않은 오류를 방지하고, 코드의 안정성을 향상시킵니다.
  2. 코드 가독성 증가
    타입 힌트를 사용하여 함수 및 변수의 의도를 명확하게 전달할 수 있습니다. 이는 코드를 이해하기 쉽게 만들고, 새로운 개발자가 코드를 이해하고 수정하는 데 도움이 됩니다.
  3. 리팩토링 향상
    정적 타입 검사는 코드를 리팩토링할 때 특히 유용합니다. 코드의 구조를 변경하거나 변수 이름을 바꿀 때, Mypy는 이러한 변경이 코드에 올바르게 반영되는지 확인할 수 있습니다.

마무리…


지금까지 설명한 파이썬 언어를 이용하여 개발할 때, 사용하면 유용한 도구들과 내용을 요약해 보겠습니다.

  • 개발 시 되도록이면 가상환경을 생성하여 가상환경 내에서 개발을 하도록 하자!
  • 복잡한 패키지 관리Poetry 도구를 통해서 관리하자!
  • 동적 타입 언어의 취약성을 보완하고자 한다면 Mypy 라이브러리를 사용하자!

파이썬 개발 환경을 구성하면서 느낀 점은 개발자마다 각자 선호하는 IDE가 있고, 자신만의 코드 스타일이 있듯이 개발 환경을 구성하는 데에도 각자만의 환경 구성이 있을 것이라 생각됩니다. 앞서 이야기한 도구들을 사용하고 개발 환경을 구성하는데 많은 시간과 비용이 들어 오히려 업무에 지장이 가지 않았으면 합니다. 그러나, 부족한 공통된 규칙 및 환경으로 인해 개발의 생산성 하락 및 비효율적인 업무의 증가 등이 많지 않았으면 하는 마음으로 몇 가지 도구들을 소개하였으니 한번 사용해 보시는 것을 추천드립니다.

이상으로 글을 마치겠습니다. 부족하지만 끝까지 읽어주셔서 감사합니다.

Reference


Scroll to Top