8강 개념 중심 ⏱ 약 25분

 

0. 학습 목표

→ 코드는 그대로인데 실행이 실패하는 이유, 즉 호환성 문제의 정체를 이해합니다.

더보기

이번 글은 개념 중심 강의입니다.

 

 

7강에서 모듈은 파일이고 패키지는 폴더라는 것을 확인했습니다.

그런데 이 파일과 폴더에는 버전이 있습니다.

 

 

그리고 Python 버전, 패키지 버전, 운영체제의 조합이 어긋나면 — 코드를 한 글자도 바꾸지 않았는데 실행이 실패합니다.

0강에서 던진 질문, "내 컴퓨터에서는 되는데 왜 다른 컴퓨터에서는 안 될까?"의 정체가 바로 이것입니다.

 

 

이번 강의에서는 익숙한 문서 파일 비유에서 출발해,

Python이 다른 언어보다 환경 관리가 특히 중요한 이유를 확인하고,

실제로 함수가 사라지고 API가 바뀌는 사례를 봅니다.

 

 

이 문제의식이 9강(가상환경에 패키지 설치)과 10~11강(버전 기록과 재현)의 동기가 됩니다.

구분 내용
이해할 것 프로그램 실행에는 코드 외에 언어 버전·패키지 버전·OS·설치 방식이 함께 작용한다는 것
정리할 것 Python에서 호환성 문제가 발생하는 세 가지 대표 유형
확인할 것 "버전 조합을 프로젝트별로 고정한다"는 해결 방향이 가상환경·requirements.txt로 이어지는 연결

 

1. 익숙한 파일 세계에서 보는 호환성

→ Word·Excel 문서의 버전 문제를 통해 호환성이라는 개념을 먼저 세웁니다.

더보기

2.1 Word 파일 예시

프로그래밍 환경의 호환성을 이해하기 전에, 먼저 우리가 익숙하게 사용하는 문서 파일을 떠올려 보겠습니다.

예를 들어 Word 2010에서 만든 .docx 파일을 Word 2019나 Word 365에서 열면 어떻게 될까요?

대부분의 경우 큰 문제 없이 열립니다. 글자, 표, 기본 서식은 대체로 유지됩니다.

이유
Word는 과거에 만든 문서를 최신 버전에서도 열 수 있도록 하위 호환성(backward compatibility)을 유지하는 방향으로 발전해 왔기 때문입니다.

 

 

 

 

2.2 PowerPoint · Excel 실행 기능 포함 문서 예시

PowerPoint 문서에는 애니메이션이 들어갈 수 있고, Excel 문서에는 매크로가 들어갈 수 있습니다.

예를 들어 다음과 같은 경우를 생각해 볼 수 있습니다.

  • PowerPoint 2013에서 만든 .pptx 파일을 PowerPoint 365에서 열기
  • Excel 2016에서 만든 .xlsm 파일을 Excel 365에서 열기

파일 자체는 열릴 수 있습니다. 하지만 애니메이션, 매크로, 외부 연결, 보안 설정과 관련된 기능은 환경에 따라 다르게 동작하거나 차단될 수 있습니다. 이를 호환성 문제라고 합니다.

요소 설명
문서 파일 글자, 표, 슬라이드, 수식 등
실행 기능 애니메이션, 매크로, 자동화 기능
실행 환경 프로그램 버전, 보안 정책, OS 설정

프로그래밍과의 연결
워드와 파워포인트, 엑셀의 예시처럼, 프로그래밍 소스 코드는 존재한다고 해서 항상 실행되는 것은 아닙니다.

소스코드가 실행되려면 그 코드에 맞는 언어 버전, 라이브러리, OS, 설정이 함께 맞아야 합니다.

 

 

2.3 프로그래밍으로 연결

이 구도가 프로그래밍에 그대로 옮겨집니다.

소스 코드는 "문서 파일"처럼 존재하지만, 그것이 실행되려면 코드에 맞는 언어 버전, 라이브러리, OS, 설정 — 즉 "실행 환경"이 함께 맞아야 합니다. 코드가 있다는 것과 코드가 실행된다는 것은 다른 문제입니다.

 

2. Python은 왜 환경 관리가 특히 중요한가?

→ 하위 호환을 중시하는 다른 언어들과 비교해, Python의 특수성을 확인합니다.

더보기

2.1 많은 언어는 하위 호환성을 중시한다

C, C++, C#, Java 같은 언어는 일반적으로 기존 코드를 오래 유지할 수 있도록 설계되는 편입니다. 예를 들어 1999년 표준(C99) 기준으로 작성된 아래 C 코드는 이후 표준인 C11, C17 환경에서도 대부분 문제없이 컴파일되고 실행됩니다.

// C99(1999년) 기준으로 작성된 코드
#include <stdio.h>

int main() {
    int x = 10;
    printf("%d\n", x);      // 20여 년이 지난 최신 표준에서도 그대로 동작
    return 0;
}

Java와 C#도 마찬가지로, 과거에 작성한 코드가 최신 환경에서 최대한 계속 동작하도록 유지하는 것을 중요하게 생각합니다. 물론 모든 상황에서 100% 호환된다는 뜻은 아니지만, 기본 방향이 그렇습니다.

 

 

 

 

2.2 Python의 특수성 — 조합이 맞아야 한다

Python도 하위 호환성을 고려합니다.

하지만 실제 Python 개발에서는 문법만 보는 것이 아니라 여러 요소의 조합이 함께 맞아야 합니다.

요소 예시
Python 버전 3.10, 3.12, 3.13
패키지 버전 NumPy, pandas, PySide6, PyTorch 등 각각의 버전
OS 환경 Windows, Ubuntu, macOS
설치 방식 apt, pip, venv
실행 위치 시스템 Python, 전역 Python, 가상환경 Python (2강의 3단 구분)

자주 발생하는 문제
코드는 맞는데, 내 컴퓨터에서는 실행되고 다른 컴퓨터에서는 실행되지 않는 경우가 있습니다.

이 문제는 대부분 Python 버전과 패키지 조합이 다르기 때문에 발생합니다.

 

 

 

 

2.3 Python은 서드파티 패키지 의존도가 높다

Python 개발은 외부 라이브러리를 많이 사용하는 방식으로 이루어지는 경우가 많습니다.

  • NumPy
  • pandas
  • matplotlib
  • PySide6
  • PyTorch
  • TensorFlow
  • FastAPI
  • Django

문제는 새 버전 Python이 나왔다고 해서 모든 패키지가 즉시 그 버전을 지원하는 것은 아니라는 점입니다.

상황 결과
Python은 최신 버전으로 설치됨 일부 패키지가 아직 지원하지 않을 수 있음
패키지는 설치되지만 wheel이 없음 빌드 오류가 발생할 수 있음
최신 패키지를 설치함 오래된 Python 버전을 더 이상 지원하지 않을 수 있음
기존 코드에서 쓰던 함수가 제거됨 실행 중 에러가 발생할 수 있음

 

그래서 "내 컴퓨터에서는 실행되는데 다른 컴퓨터에서는 안 된다"는 문제의 원인은 대부분 두 컴퓨터의 Python 버전·패키지 버전 조합이 다르기 때문입니다. 코드가 아니라 조합이 문제인 것입니다.

 

3. 실제 문제 사례 

→ 표준 라이브러리와 외부 패키지에서 실제로 일어난 호환성 문제를 확인합니다.

더보기

3.1 유형 1 — 표준 라이브러리에서 함수가 제거된다

7강에서 확인한 random.py 같은 표준 라이브러리는 "표준"이니 바뀌지 않을 것 같지만, 그렇지 않습니다.

아래는 과거에 실행 시간 측정용으로 널리 쓰이던 코드입니다.

import time

start = time.clock()      # 과거에 널리 쓰이던 시간 측정 함수

# ... 작업 ...

end = time.clock()        # Python 3.8부터는 이 줄에서 AttributeError 발생

 

 

time.clock()은 Python 3.3부터 사용 자제(deprecated) 안내가 붙었고, Python 3.8에서 완전히 제거되었습니다.

공식 문서는 대신 time.perf_counter() 또는 time.process_time()을 사용하라고 안내합니다.

이런 제거는 한 건이 아닙니다.

 

 

기존 코드 제거된 버전 대체 방법
time.clock() Python 3.8 time.perf_counter()
fractions.gcd() Python 3.9 math.gcd()
base64.encodestring() Python 3.9 base64.encodebytes()
base64.decodestring() Python 3.9 base64.decodebytes()

즉, 같은 코드라도 Python 3.7에서는 실행되고 3.8에서는 오류가 납니다.

어느 Python으로 실행하느냐가 실행 성공 여부를 결정하는 것입니다.

 

 

 

 

3.2 유형 2 — 외부 패키지의 API가 바뀐다

import numpy as np

x = np.int(3)          # 과거 NumPy에서는 동작하던 코드
y = np.float(3.14)     # 최신 NumPy에서는 AttributeError 발생

과거에는 위 코드가 동작하는 경우가 많았지만, NumPy 버전이 올라가면서 np.int, np.float 같은 표현은 제거되었습니다. 문제는 연쇄 효과입니다. 오래된 소스 코드나 오래된 다른 라이브러리가 이 표현을 아직 쓰고 있다면, 그것을 실행하기 위해 구버전 NumPy가 필요하고, 구버전 NumPy는 구버전 Python에서만 지원될 수 있습니다.

오래된 코드가 np.int 사용
        ↓
구버전 NumPy 필요
        ↓
구버전 NumPy는 구버전 Python에서만 지원
        ↓
결국 "이 프로젝트는 Python 3.x + NumPy 1.x 조합"으로 고정됨      ← 조합이 사슬처럼 엮인다

 

 

 

 

3.3 유형 3 — 패키지가 Python 버전을 요구한다

 

Python 다양한 버전이 존재하며,

다양한 Python 외부 라이브러리를 많이 사용하는 언어입니다.

 

예를 들어

데이터 분석을 할 때는 NumPy, pandas를 사용하고,

GUI 프로그램을 만들 때는 PySide6를 사용할 수 있습니다.

인공지능 학습을 할 때는 PyTorch, TensorFlow 같은 라이브러리를 사용하기도 합니다.

프로젝트 필요한 환경 예시
데이터 분석 프로젝트 Python 3.10, pandas, NumPy
GUI 프로그램 프로젝트 Python 3.11, PySide6
AI 모델 학습 프로젝트 Python 3.10, PyTorch, TensorFlow

 

문제는,

Python 개발 프로젝트마다 필요한 Python 버전과 라이브러리 버전이 달라 문제가 생길 수 있습니다.

 

예를 들어,

System Python에서는 Python 3.10과 PySide6 6.5 라이브러리 버전이 설치되어 있다면

System Python 버전 (전역)
Python 3.10
PySide6 6.5

 

A 프로젝트에서는 Python 3.10과 PySide6 6.5 라이브러리 버전이 필요할 때 문제가 없습니다.

A 프로젝트
Python 3.10
PySide6 6.5

 

반면,

B 프로젝트에서는 더 최신 Python과 PySide6 6.7 같은 다른 라이브러리 버전이 필요할 수 있습니다.

 
A 프로젝트 →  B 프로젝트
Python 3.10  →  Python 3.12
PySide6 6.5  →  PySide6 6.7

 

B 프로젝트를 진행하면서 PySide6 6.7로 라이브러리를 업그레이드하거나, System Python의 버전을 변경하면
A 프로젝트가 갑자기 정상적으로 실행되지 않을 수 있습니다. 그리고 운영체제 System 자체게 문제가 발생할 수 있습니다.

 

4. 해결 방향 — 조합을 프로젝트별로 고정한다

→ 호환성 문제의 해법이 지금까지 배운 가상환경, 그리고 앞으로 배울 버전 기록으로 모이는 것을 확인합니다.

더보기

4.1 가상환경(venv) 이 필요한 이유

 

해결방법은 

Python 개발에서는 프로젝트마다 독립된 실행 환경인 가상환경을 만들어 사용해

서로 다른 프로젝트들이 서로 영향을 주지 않도록 관리합니다.

System Python 환경
Python 3.10
PySide6 6.5

A 프로젝트 가상환경
Python 3.10
PySide6 6.5

B 프로젝트 가상환경
Python 3.12
PySide6 6.7

 

이렇게 하면 B 프로젝트에서 라이브러리를 업그레이드하더라도
A 프로젝트의 환경에는 영향을 주지 않습니다.

 

 

 

 

4.2. 가상환경

가상환경은 프로젝트마다 독립된 Python 실행 환경을 만들어주는 기능입니다.

예를 들어 A 프로젝트와 B 프로젝트가 서로 다른 패키지 버전을 사용해야 할 수 있습니다.

프로젝트 Python 버전 주요 패키지
A 프로젝트 Python 3.10 NumPy 1.23, pandas 1.5
B 프로젝트 Python 3.12 NumPy 2.x, pandas 2.x

이 두 프로젝트를 하나의 전역 환경에서 관리하면 충돌이 발생할 수 있습니다. 그래서 Python에서는 프로젝트마다 가상환경을 만들어 사용하는 것이 좋습니다.

python3 -m venv .venv
source .venv/bin/activate

 

 

 

 

4.3. 패키지 버전 기록

가상환경을 만들었다면, 그 안에 어떤 패키지를 설치했는지도 기록해야 합니다.

대표적인 방식이 requirements.txt입니다.

pip freeze > requirements.txt

이 파일에는 현재 프로젝트에서 사용 중인 패키지 목록과 버전이 기록됩니다.

다른 컴퓨터에서 같은 환경을 만들 때는 다음 명령을 사용할 수 있습니다.

pip install -r requirements.txt

 

 

 

 

4.4. 최종 정리

 

지금까지 본 문제들의 공통 원인은 하나입니다. 실행에 필요한 버전 조합이 환경마다 다르다는 것.

그렇다면 해결책도 하나로 모입니다 — 프로젝트마다 "동작하는 조합"을 고정하고,

그 조합을 어디서든 재현할 수 있게 만드는 것입니다.

해결 요소 역할과 해당 강의
특정 버전 Python 설치 프로젝트가 요구하는 Python 버전을 준비 — 5강에서 완료
가상환경 (venv) 프로젝트별로 Python 버전 + 패키지 조합을 격리 — 4·6강에서 완료
가상환경 안에 패키지 설치 조합을 가상환경 내부에 고정 — 9강에서 실습
requirements.txt 고정한 조합을 기록하고 다른 환경에서 재현 — 10·11강에서 학습

돌아보면 A 프로젝트는 Python 3.12 + PySide6 6.5 조합, B 프로젝트는 Python 3.13 + PySide6 6.7 조합처럼 프로젝트마다 다른 조합이 필요할 수 있다는 것이 호환성 문제의 결론이고, 그 조합을 프로젝트 폴더 안에 각각 격리해 주는 도구가 바로 지금까지 만들어 온 가상환경입니다. 이제 이론은 충분합니다. 다음 강의부터 이 조합을 실제로 채우고 기록합니다.

- 코드가 있다는 것 ≠ 코드가 실행된다는 것 — 실행은 버전 조합의 문제다
- Python은 외부 패키지 의존도가 높아, Python·패키지 버전이 사슬처럼 엮인다
- 표준 라이브러리조차 버전에 따라 함수가 제거된다 (time.clock 등)
- 해법 = 프로젝트별로 조합을 고정(가상환경)하고 기록(requirements.txt)한다

→ 다음 강의 (9강): 6강에서 만든 test_venv2(Python 3.13)에 PySide6를 설치합니다. 핵심은 설치 자체가 아니라, pip show의 Location으로 패키지가 시스템이 아닌 가상환경 내부에 격리 설치되었는지 검증하는 것 — 이번 강의에서 말한 "조합의 고정"이 실제로 일어나는 순간을 확인합니다.