🐍 파이썬 ↔ C 관계 & 가상환경
1. 파이썬과 C의 관계
파이썬(특히 CPython)은 사실상 C로 구현된 인터프리터예요.
- CPython: 가장 널리 쓰이는 파이썬 구현체 (Python 공식 배포판)
- 핵심 원리:
- 파이썬 소스 코드 → **바이트코드(.pyc)**로 컴파일
- 이 바이트코드를 **C로 작성된 인터프리터(CPython VM)**가 실행
- 파이썬 객체(PyObject)는 C 구조체로 관리됨
즉:
- 파이썬은 "문법과 문화를 가진 언어"
- CPython은 "C로 만들어진 실행기"
a = 10
- a는 스택에 참조 저장
- 10은 힙에 PyLongObject라는 C 구조체로 생성
👉 파이썬에서 int, list 같은 객체들은 실제로 C 언어 구조체에 불과함.
2. 왜 C 기반으로 동작할까?
- 성능: C는 저수준 언어라서 메모리와 CPU 제어에 강함
- 확장성: 파이썬 라이브러리 중 NumPy, Pandas, TensorFlow 등이 내부적으로 C/C++로 구현됨
- 호환성: 운영체제 API와 쉽게 연동 가능
따라서, 파이썬은 편리한 문법 + C의 성능을 동시에 가져가는 구조임.
3. 가상환경(virtual environment)의 개념
가상환경은 파이썬 프로젝트별 독립적인 실행 환경이에요.
- 일반적으로 파이썬은 전역(Global) 환경에 설치되는데,
- 프로젝트마다 필요한 패키지 버전이 다르기 때문에 충돌 문제 발생
- 이를 해결하기 위해 가상환경을 사용
📌 장점:
- 프로젝트별 패키지/라이브러리 버전 격리
- 시스템 파이썬에 영향 주지 않음
- 배포 시 환경 복제 용이
4. 가상환경 동작 원리
- 가상환경을 만들면 특정 디렉토리에
- bin (또는 Scripts): 파이썬 실행 파일
- lib: 설치된 패키지 저장
- pyvenv.cfg: 가상환경 설정
이 생성됨
- 활성화 시, PATH 환경변수가 바뀌어 해당 디렉토리 안의 파이썬을 사용하게 됨.
# 가상환경 생성
python -m venv myenv
# 활성화
source myenv/bin/activate # macOS/Linux
myenv\Scripts\activate # Windows
3. 종료 시에는 PATH가 원래대로 돌아옴.
deactivate
5. 가상환경과 C의 관계
- 가상환경은 파이썬 실행 파일과 **해당 실행기에 필요한 라이브러리(C 기반 모듈 포함)**를 격리된 디렉토리에 모아둔 것.
- 예를 들어, NumPy 같은 패키지는 내부적으로 C 코드로 되어 있는데, 가상환경 안에 설치되면 그 환경 안에서만 접근 가능.
[시스템 파이썬] ----+
|
+--> [가상환경 myenv]
| ├─ bin/python (별도 실행기)
| ├─ lib/site-packages (패키지들)
| └─ C 기반 모듈 (numpy, pandas 등)
|
+--> [가상환경 projectX]
├─ bin/python
├─ lib/site-packages
└─ 다른 버전의 패키지들
✅ 정리
- 파이썬은 C로 만들어진 CPython 위에서 동작하며, 실제 객체는 C 구조체임
- 가상환경은 프로젝트별로 파이썬 인터프리터와 라이브러리를 격리시켜주는 시스템임
🐍 파이썬 실행 과정 (C, 인터프리터, 컴파일러, 메모리 관점)
1. 파이썬 코드 → 실행까지 흐름
.py 파일 작성
↓
[컴파일러] Python Compiler
↓ 바이트코드(.pyc) 생성
[인터프리터] CPython Virtual Machine
↓ 바이트코드 해석
[메모리] 스택/힙에 객체 배치
↓
CPU에서 실행
2. 단계별 설명
(1) 소스코드 작성
- 우리가 작성한 .py 파일은 순수 텍스트
x = 10
y = 20
print(x + y)
(2) 파이썬 컴파일러
- 파이썬도 컴파일러를 갖고 있음 (단, 기계어가 아니라 바이트코드로 변환)
- 결과물: 바이트코드(.pyc)
- 보통 __pycache__ 폴더에 저장됨
python -m py_compile script.py
바이트코드 예시 (추상화):
LOAD_CONST 10
STORE_NAME x
LOAD_CONST 20
STORE_NAME y
LOAD_NAME print
CALL_FUNCTION 1
(3) CPython 인터프리터
- 바이트코드를 한 줄씩 읽어 실행
- 이때 내부적으로는 **C로 구현된 가상머신 (CPython VM)**이 동작
- eval_frame 같은 C 함수가 바이트코드를 처리
즉:
- 컴파일러: .py → .pyc
- 인터프리터: .pyc → 실제 실행
(4) 메모리 구조 활용
실행 시 메모리 구성:
- 스택 (Stack)
- 함수 호출 시 로컬 변수 이름과 객체 참조(포인터) 저장
- x, y 같은 변수명 존재
- 힙 (Heap)
- 실제 객체 데이터 저장 (10, 20, 리스트 등)
- 모든 파이썬 객체는 힙에 있음
- 객체는 C 구조체(PyObject) 형태
- GC (Garbage Collector)
- 참조 카운트 + 세대별 수집으로 메모리 해제 관리
3. C와의 관계
- CPython은 C로 작성됨 → 바이트코드를 C 함수들이 해석
- 파이썬 객체는 모두 C 구조체
- 수학 연산이나 리스트 조작 등은 결국 C 코드 함수 호출
a = [1,2,3]
- a (스택에 저장된 이름)
- [1,2,3] (힙에 저장된 PyListObject → 내부적으로 C 배열)
4. 그림으로 이해하기
[파이썬 코드] .py
↓ 컴파일러
[바이트코드] .pyc
↓ 인터프리터(CPython VM)
┌─────────────────────┐
│ C로 구현된 가상머신 │
│ (eval_frame 등) │
└─────────┬───────────┘
│
┌────┴─────┐
│ 메모리 구조│
│ │
│ [스택] │ → 변수 참조 저장
│ [힙] │ → 객체(PyObject) 저장
│ [GC] │ → 참조 카운트 & 순환 수집
└───────────┘
5. 정리
- 컴파일러: .py를 **바이트코드(.pyc)**로 변환
- 인터프리터: 바이트코드를 C로 작성된 가상머신에서 실행
- 메모리 구조:
- 스택 → 변수 참조 저장
- 힙 → 실제 객체 저장
- GC → 메모리 자동 해제
- C의 역할: CPython 구현, 객체 구조 정의, 핵심 함수 실행
반응형
'Programing Language > Python' 카테고리의 다른 글
파이썬 메모리 구조 개요 (2) | 2025.07.29 |
---|---|
Python 데코레이터(Decorator) (0) | 2024.11.27 |