python은 왜 가상환경을 사용할까 (python과 javascript 간단히 비교해보기)

2025. 1. 3. 21:29·기타

영상을 보고 정리하는 데에 걸리는 시간을 줄이고 싶어서, Python으로 비디오 스크립트를 분석하고 내용을 요약해주는 프로그램을 만들다 문득 이런 궁금증이 들었습니다.

 

"왜 다른 언어들은 굳이 가상환경을 사용하지 않아도 잘 동작하는데, Python은 가상환경을 사용하는 걸까?"


그래서 제가 사용하는 주 언어인 Javascript와 비교하며 정리해보게 되었습니다!
우선 가상환경의 역할을 한줄요약하자면 '전역 환경과 별도로 각 프로젝트만의 Python 인터프리터와 패키지 환경을 생성해준다.' 입니다.


위 질문에 대해 결론부터 말하자면...

 

python 은 기본적으로 전역환경에 패키지를 다운로드합니다.그런데 프로젝트별로 인터프리터 버전과 패키지를 따로 관리하고자 하는 필요성이 대두되며~ 전역과는 독립된, 서로 영향을 받지않는 가상환경을 생성하여 프로젝트를 효율적으로 관리 (필요한 패키지만 포함하는 등)합니다.
javascript(엄밀히 말하면 node.js)는 기본적으로 프로젝트 폴더 내부에 node_modules 폴더를 만들고 그곳에 필요한 패키지를 다운로드하고 사용합니다. 그러나 런타임인 node.js는 전역으로 설치되어 모든 프로젝트에서 공통으로 사용합니다.
 
이처럼 두 언어 각각의 생태계와 패키지 관리 방식이 다르기 때문에 가상환경 사용 여부에도 차이가 나게됩니다. 그럼 이제 JavaScript와 Python의 주요 패키지 관리 방식과 실행환경의 차이를 비교해보겠습니다.
 
 

1. 설치 구조의 차이

JavaScript (Node.js):

JavaScript는 프로젝트 단위로 의존성을 관리합니다. (npm, yarn 같은 패키지 관리 도구를 통해)

  • 프로젝트 디렉토리마다 node_modules 폴더가 생성되고, 여기에 해당 프로젝트에 필요한 라이브러리들이 설치됩니다.
  • 그렇기 때문에, 동일한 라이브러리라도 각 프로젝트마다 다른 버전을 사용할 수 있으며, 프로젝트별로 라이브러리가 격리됩니다.

   => 프로젝트 별로 설치된 라이브러리끼리 서로 영향을 주지 않아 버전이 충돌하지 않습니다. 
 

project-a/
  ├── package.json
  ├── node_modules/
      ├── express@4.17.0
project-b/
  ├── package.json
  ├── node_modules/
      ├── express@5.0.0

 
 

Python:

Python은 기본적으로 라이브러리를 전역환경에 설치합니다.

  • 전역적으로 설치된 라이브러리는 기본적으로 모든 프로젝트에서 공유됩니다. 따라서 같은 라이브러리를 다른 버전으로 사용하는 프로젝트가 있으면 충돌이 발생할 수 있습니다.
  • 전역으로 같은 라이브러리에 대해 다른 버전을 설치하게 되면, 뒤늦게 설치된 버전으로 덮어씌워집니다 

       => 이 문제를 해결하기 위해 프로젝트별로 독립적인 환경을 만드는 가상환경(venv)이 필요합니다.
 

Global Environment:
  ├── Django@3.2
project-a/ (Uses Django@3.2)
project-b/ (Requires Django@4.0 -> Conflict!) 

 

2. 패키지 의존성 관리의 차이

JavaScript:

JavaScript(node.js)는 각 프로젝트 별 폴더에서 package.json 파일을 사용해 프로젝트 의존성을 명시적으로 관리합니다.

  • 각 패키지는 자신의 의존성도 포함하고 있습니다. (패키지 버전이 달라지면 해당 패키지에서 요구하는 의존성도 달라질 수 있기 때문)
  • 프로젝트별로 node_modules 폴더를 생성하여 의존성을 격리하므로, 한 프로젝트의 패키지가 다른 프로젝트에 영향을 미치지 않습니다.

 

Python:

Python에서는 requirements.txt 파일을 사용해 프로젝트 의존성을 관리할 수 있습니다.

  • 전역 환경에서 의존성을 공유하면, 한 프로젝트에서 업데이트한 패키지가 다른 프로젝트에 영향을 미칩니다. 그렇기에 각 프로젝트 별 가상환경을 생성 하고 그 안에서 프로젝트 의존성을 관리합니다.

1. 가상환경을 생성합니다

python -m venv myenv

2. 다음과 같은 구조를 가진 가상환경이 현재 폴더 내부에 생성됩니다

myenv/
  ├── bin/       # 실행 파일 (Windows에서는 Scripts/)
  ├── lib/       # 라이브러리가 설치될 파일
  ├── include/   # C 헤더 파일 (필요 시)
  └── pyvenv.cfg # 가상환경 설정 파일

 
3. 가상환경을 활성화합니다

source myenv/bin/activate

 
4.가상환경을 활성화한 상태에서 pip 명령어를 사용해 필요한 라이브러리를 설치합니다.
5. 라이브러리가 lib폴더에 설치됩니다. (전역 환경에 영향을 미치지 않음)
6. 프로젝트에서 설치한 모든 라이브러리(=의존성 목록)를 requirements.txt 파일로 저장합니다.

pip freeze > requirements.txt

7. 현재 가상환경에 설치된 모든 패키지, 버전 정보가 requirenments.txt 파일로 저장됩니다.

django==4.2.0
requests==2.26.0

 
 

이렇게 저장된 의존성 정보는 해당 텍스트 파일을 사용하여 `pip install -r requirements.txt`를 통해 재현 가능합니다.

이는 Node.js 환경에서 'npm install' 명령으로 'package.json'에 정의된 의존성을 설치하는 것과 비슷하지만, Python의 'requirements.txt'는 'package.json'과 달리 하위 의존성 정보는 포함하지 않습니다.

 

3. 실행 환경의 차이

JavaScript:

위에서 봤듯이 각 프로젝트는 독립된 node_modules 폴더를 사용합니다. (명시된 패키지 버전을 각 폴더 내부에 다운받음) 
그러나 실행 환경 자체(Node.js 런타임 버전)는 모든 프로젝트에서 동일하게 공유됩니다.
 
추가로 특정 프로젝트에서 Node.js의 명시된 다른 버전을 사용해야한다면, nvm 이라는 명령어를 통해 해당 폴더 내에서만 사용할 node 버전을 다운받고 명시하여 사용할 수 있습니다
 
[개념 정리]

  • Node.js = V8 엔진 + 비동기 I/O 처리 라이브러리(libuv) + 코어 모듈 + npm으로 구성된 통합 환경이자 런타임 (즉, JavaScript가 브라우저 외부에서도 실행 가능한 환경)
  • Node.js에서 V8 엔진의 역할 = JavaScript를 기계어로 번역하여 OS에서 실행 가능하게 만듦 (JIT 컴파일러 기반)
  • JIT 컴파일러 = 브라우저가 스크립트를 실행하려고 할 때 컴파일하는 방식

Python:

Python은 기본적으로 전역 Python 인터프리터(런타임)와 라이브러리를 공유하기 때문에 실행 환경이 독립적이지 않습니다.

  • 이를 해결하기 위해, 가상환경을 구축하고 특정 프로젝트에서 사용할 Python 인터프리터와 라이브러리를 가상환경 안에 설치하여 다른 python 프로젝트와 격리합니다.
  • 가상환경을 활성화하면 해당 프로젝트만의 독립적인 실행 환경이 제공되어, 프로젝트 간 충돌을 방지합니다. 

4. 탄생 배경의 차이

JavaScript:

JavaScript 생태계는 웹 개발 중심으로 설계되었습니다.

  • 프로젝트마다 독립적인 환경이 요구되는것을 전제로, npm과 yarn은 이를 반영해 프로젝트 기반 의존성 관리를 기본 설계로 채택했습니다.
  • 따라서, Node.js는 런타임을 공유하더라도, 패키지 충돌 없이 독립적인 프로젝트 실행이 가능합니다.

 

Python:

Python은 범용 프로그래밍 언어로 설계되었습니다.

  • 초기에는 가상환경 개념이 포함되어 있지 않았고, 대부분의 Python 프로젝트는 동일한 시스템 환경에서 실행되었습니다.
  • 시간이 지나며 프로젝트별 독립성을 보장해야 할 필요성이 커졌고, 이를 해결하기 위해 가상환경이 도입되었습니다.

 

요약 : 왜 Python은 실행 환경까지 격리하고, Node.js는 패키지 수준의 독립성만으로 충분할까? 

 Node.js :

  • 대부분의 Node.js 프로젝트는 동일한 런타임에서 문제없이 실행됩니다.
    • Node.js에서 사용되고 업데이트 되는 라이브러리들은 모든 버전의 Node.js와 호환됩니다
  • 추가적인 런타임 격리가 필요한 경우는 드물며, 필요할 경우 nvm으로 관리 가능합니다.
    • 프로젝트 별로 node_modules라는 폴더를 만들고 그 내부에 한해서만 필요한 라이브러리를 설치해서 사용하는 것으로 충분히 환경이 격리 됩니다.

 

Python :

  • 프로젝트마다 다른 Python 인터프리터 버전과 라이브러리 버전을 요구할 가능성이 높습니다.
  • 데이터 과학, 머신러닝에서 사용되는 C 기반 라이브러리(Numpy, Pandas 등)는 OS 환경과 밀접하게 연관되므로, 충돌 방지를 위해 가상환경이 필요합니다.

 

한줄 정리

= python은 런타임까지 격리해야해서 가상환경이 필요하다~!

  • Node.js: 런타임 공유함 + 패키지 독립성 유지함 → 가상환경 불필요
  • Python: 런타임 격리함 + 패키지 독립성 유지함 → 가상환경 필요

 


Python 가상환경 생성 및 실행하기

사실 가상환경 생성과 활성화 자체는 매우 간단합니다
 
가상환경 설치 & 활성화하기

python3 -m venv youtube_env
source youtube_env/bin/activate

 

위의 명령어 뜻풀이를 해보겠습니다

python3 -m venv env_name
= venv라는 python3 모듈을 사용하여 env_name라는 이름의 가상환경을 만든다

 
python 3 : 사용하려는 Python 버전. 기본적으로 Python 3 이상 버전에서 가상환경 생성이 가능함

  • python3 대신 python으로도 사용할 수 있지만, 명시적으로 버전을 지정하면 Python 환경이 다수 설치된 경우에 더 안전하게 실행됩니다.

-m : Python에서 제공하는 모듈 실행 플래그

  • 여기서는 Python에 내장된 venv 모듈을 실행합니다. 모듈을 호출해서 가상환경을 생성해주는 것이죠

venv : 가상환경 생성 도구 (모듈)

  • Python 표준 라이브러리에서 제공하는 가상환경 생성 도구입니다. 별도의 설치 없이 기본적으로 Python 3.3 이상에서 제공됩니다.
  • 가상환경 생성 시, Python 실행 파일과 기본 라이브러리를 포함한 독립적인 환경을 만듭니다.

env_name :  생성할 가상환경 이름 지정.

  • ex. youtube_env

 
 

source youtube_env/bin/activate
= 가상환경 활성화 하기 -> 이후로는 가상환경 내부로 들어가서 가상환경에서 작업이 진행됨
 
source : Unix 계열(Linux, macOS)에서 스크립트를 실행하는 명령어

  • 여기서는 activate 스크립트를 실행해 가상환경을 활성화합니다.

youtube_env/bin/activate: 가상환경을 활성화하는 스크립트의 경로.

  • 이 스크립트가 활성화되면 터미널에 가상환경 이름이 표시됩니다.
(youtube_env) user@host:~$

 
 
 

가상환경에서 작업하기

  1. 라이브러리 설치
    가상환경이 활성화된 상태에서 필요한 라이브러리를 설치합니다:
pip install <package_name>
  • pip : python 패키지 관리자
    • PyPI(Python Package Index)에서 지정한 패키지를 다운로드하여 설치해줌

2. 의존성 저장
가상환경에서 설치된 라이브러리를 기록하려면:

pip freeze > requirements.txt

 
3. 의존성 복원
다른 환경에서 동일한 의존성을 설치하려면:

pip install -r requirements.txt

 
 

작업 끝내기

= python 가상환경 비활성화하기

deactivate
  • 가상환경이 활성화된 상태에서 이 명령어를 입력해주면 가상환경이 종료되고 다시 기본 환경으로 돌아옵니다

 
 
파이썬을 하다 되려 js에 대해 기본적이라 생각했던 부분을 다시 생각해보는 계기가 되었네요🧐

'기타' 카테고리의 다른 글

M1 VSCode에서 C++의 'bits/stdc++.h' 헤더 파일 불러오기 오류 해결 과정  (1) 2024.09.04
깃허브 협업 방식 정리  (1) 2023.12.20
mac m1 tensorflow 설치 중 conda python 버전 관련 에러 해결법  (2) 2023.02.28
'기타' 카테고리의 다른 글
  • M1 VSCode에서 C++의 'bits/stdc++.h' 헤더 파일 불러오기 오류 해결 과정
  • 깃허브 협업 방식 정리
  • mac m1 tensorflow 설치 중 conda python 버전 관련 에러 해결법
c_jm
c_jm
  • c_jm
    c_jm
    c_jm

    🎋 어제보다 발전한 오늘

  • 전체
    오늘
    어제
    • 분류 전체보기 (36)
      • 프로젝트 (6)
      • 백준 문제풀이 (19)
      • 프로그래머스 문제풀이 (4)
      • 공부 (1)
      • 문제 해결 (2)
      • 기타 (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    도커컴포즈
    docker
    jquery
    티스토리 다크모드
    인라인 css
    reverse proxy
    홈서버
    백준 #1152 #c++
    nginx
    리버스 프록시 서버
    html
    도커
    복붙
    글자색
    docker-compose.yml
    리버스 프록시
    docker-compose
    다크모드
    코드블럭
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
c_jm
python은 왜 가상환경을 사용할까 (python과 javascript 간단히 비교해보기)
상단으로

티스토리툴바