파이썬 시작하기 - 설치 실행과 들여쓰기가 문법인 이유 (파이썬 초급 1단원)
이 단원에서 배우는 것
파이썬 초급 커리큘럼의 첫 단원이다. 앞 단원은 없다. 대신 8단원까지 계속 쓸 소재를 여기서 정한다. 동네 서점의 재고와 판매 기록이다. 책 제목·가격·재고 수량 같은 데이터를 1단원에서는 한 줄 출력으로, 8단원에서는 여러 파일로 나뉜 패키지로 다룬다. 소재가 같으니 매 단원 새로 이해할 것은 문법 하나뿐이다. 이번 단원은 그 첫 코드를 실행하기까지의 환경, 그리고 파이썬이 다른 언어와 구조적으로 다른 두 지점을 다룬다.
- 인터프리터 언어라는 말이 실무에서 무엇을 바꾸는지 설명한다.
- 파이썬을 설치하고 가상환경을 만들어 스크립트를 실행한다.
- 들여쓰기가 왜 문법인지, 그래서 무엇이 오류가 되는지 안다.
왜 필요한가
자바나 C로 만든 프로그램은 빌드라는 단계를 거친다. 빌드가 끝나면 .class나 실행 파일이라는 산출물이 남고, 그 산출물을 서버에 올린다. 빌드가 성공했다는 것은 최소한 "문장이 말이 되는지"는 전부 검사했다는 뜻이다. 오타 하나가 있으면 배포는커녕 빌드가 안 된다.
파이썬에는 그 단계가 없다. 우리가 서버에 올리는 것은 우리가 작성한 .py 텍스트 파일 그 자체이고, 실행할 때 파이썬이 그 텍스트를 위에서부터 읽어 내려가며 해석한다. 여기서 실무적으로 중요한 두 가지가 나온다.
첫째, 실행 환경이 프로그램의 일부다. 산출물이 없으니 "내 노트북에서는 되는데 서버에서는 안 되는" 상황의 원인이 대부분 파이썬 버전과 설치된 라이브러리 목록의 차이가 된다. 그래서 파이썬에서는 프로젝트마다 독립된 환경을 만드는 일이 선택이 아니라 기본이다. 이걸 뒤에서 볼 가상환경이 담당한다.
둘째, 오타는 그 줄이 실행될 때 터진다. 한 번도 실행되지 않은 조건 분기 안에 변수 이름 오타가 있으면, 그 코드는 배포되고 몇 주가 지난 뒤 하필 그 조건이 참이 되는 날 처음으로 죽는다. 빌드가 잡아 주지 않으니 사람이 잡아야 한다. 파이썬 진영이 테스트 코드와 정적 분석 도구를 유난히 강조하는 이유가 이것이다. 초급 단계에서 할 일은 간단하다. 짧게 쓰고, 자주 실행해 본다.
들여쓰기도 같은 맥락에서 보면 이해가 쉽다. 다른 언어는 블록의 시작과 끝을 중괄호로 표시하고, 들여쓰기는 사람 보기 좋으라고 하는 장식이다. 그래서 중괄호와 들여쓰기가 어긋난 코드가 얼마든지 존재할 수 있고, 그런 코드는 사람을 속인다. 파이썬은 장식을 없애고 들여쓰기 자체를 블록으로 삼았다. 눈에 보이는 구조와 실제 구조가 어긋날 수 없다. 대가로, 공백 하나가 문법 오류가 된다.
문법과 예제
버전 확인
이 커리큘럼은 파이썬 3.11 이상을 기준으로 한다. 먼저 터미널에서 설치 여부와 버전을 확인한다.
python3 --version
# Python 3.11.9 ← 이런 식으로 나오면 된다
맥과 리눅스에서는 명령이 python3이다. 윈도우에서는 공식 설치본을 쓰면 python 또는 py다. 맥·리눅스에 딸려 오는 python은 없거나 낡은 2.x일 수 있으므로, 습관적으로 python3을 친다.
가상환경 만들기
프로젝트 폴더를 만들고 그 안에 전용 파이썬 환경을 만든다. 표준 라이브러리에 들어 있는 venv 모듈을 쓴다.
mkdir bookstore
cd bookstore
python3 -m venv .venv
# 활성화 (맥/리눅스)
source .venv/bin/activate
# 활성화 (윈도우 PowerShell)
.venv\Scripts\Activate.ps1
활성화되면 프롬프트 앞에 (.venv)가 붙는다. 이 상태에서 pip install로 설치한 라이브러리는 전부 .venv 폴더 안에만 들어간다. 다른 프로젝트가 요구하는 버전과 충돌하지 않고, 폴더를 지우면 흔적 없이 사라진다. deactivate를 치면 빠져나온다.
두 가지 실행 방법
파이썬을 쓰는 방법은 두 가지다. 한 줄씩 쳐서 즉시 결과를 보는 대화형 모드(REPL)와, 파일에 적어 두고 실행하는 스크립트 모드다.
$ python3
Python 3.11.9 (main, ...)
>>> 12000 * 3
36000
>>> print("파이썬 개론")
파이썬 개론
>>> exit()
>>>는 파이썬이 입력을 기다린다는 표시이지 우리가 치는 글자가 아니다. REPL은 "이 함수 결과가 뭐더라"를 5초 만에 확인하는 용도다. 실무 코드는 전부 파일에 쓴다.
이제 inventory.py 파일을 만든다. 이 파일이 이번 배치 내내 자라날 서점 프로그램의 시작이다.
# inventory.py - 서점 재고 출력 (1단원)
title = "파이썬 개론"
price = 28000
stock = 3
print("책 이름:", title)
print("정가:", price, "원")
print("재고:", stock, "권")
# 재고가 없을 때만 경고를 찍는다.
# if 문은 4단원에서 제대로 다룬다. 여기서는 들여쓰기 모양만 본다.
if stock == 0:
print("품절입니다")
print("입고 예정일을 확인하세요")
print("출력 끝")
$ python3 inventory.py
책 이름: 파이썬 개론
정가: 28000 원
재고: 3 권
출력 끝
여기서 봐야 할 것은 마지막 네 줄이다. if 줄 끝의 콜론은 "아래에 블록이 온다"는 신호이고, 그다음 같은 칸만큼 들여쓴 연속된 줄이 그 블록이다. print("출력 끝")은 들여쓰기를 되돌렸으므로 블록 밖이고, 그래서 재고가 3권이든 0권이든 항상 실행된다. 중괄호도 end 키워드도 없다. 왼쪽 여백이 전부다.
들여쓰기 칸 수는 문법상 일정하기만 하면 되지만, 공식 스타일 가이드(PEP 8)는 스페이스 4칸을 정했고 현업 코드는 사실상 전부 이걸 따른다. 예외를 만들 이유가 없다.
주석과 출력
# 우물 정 기호부터 줄 끝까지는 주석이다. 실행되지 않는다.
print("정가", price) # 콤마로 넘기면 사이에 공백 한 칸이 들어간다
print("정가", price, sep=":") # 구분자를 바꾼다 -> 정가:28000
print("계산 중", end="") # 줄바꿈 없이 이어 붙인다
print("...완료") # -> 계산 중...완료
파이썬에는 /* */ 같은 여러 줄 주석 문법이 없다. 여러 줄을 주석 처리할 때는 각 줄 앞에 #을 붙인다. 에디터가 단축키로 해 준다.
실무에서 자주 틀리는 것
1. 가상환경을 만들지 않고 시스템 파이썬에 설치한다
가상환경 없이 pip install을 치면 최근 배포판에서는 아예 다음과 같이 거절당한다.
error: externally-managed-environment
이때 인터넷 검색으로 나오는 --break-system-packages 옵션을 붙이면 설치는 된다. 이름 그대로 시스템 패키지를 깨뜨리는 옵션이다. 운영체제 자체가 쓰는 파이썬 라이브러리 버전을 갈아 끼우는 짓이라, 나중에 시스템 도구가 이유 없이 죽는다. 이 오류는 "가상환경을 안 만들었다"는 신호이므로, 답은 언제나 python3 -m venv .venv다.
2. 탭과 스페이스를 섞는다
화면에서는 똑같이 4칸으로 보이지만 파이썬에게는 다른 문자다. 섞이면 이렇게 죽는다.
TabError: inconsistent use of tabs and spaces in indentation
대개 웹에서 코드를 복사해 붙였을 때 생긴다. 눈으로는 절대 못 찾으니, 에디터에서 탭을 스페이스로 변환 설정을 켜 두고 시작한다. VS Code라면 화면 오른쪽 아래의 Spaces: 4 표시를 확인하면 된다.
3. 파일 이름을 표준 라이브러리와 똑같이 짓는다
random.py, json.py, csv.py, email.py 같은 이름으로 연습 파일을 만드는 순간 문제가 시작된다. 파이썬은 라이브러리를 찾을 때 현재 폴더를 먼저 뒤지기 때문에, 진짜 표준 모듈 대신 내가 만든 파일을 집어 온다. 그러면 전혀 상관없어 보이는 곳에서 AttributeError가 난다. 이 규칙의 이유는 8단원에서 import 동작을 볼 때 확실해진다. 지금은 파일 이름 앞에 my_를 붙이거나 inventory.py처럼 도메인 이름을 쓰면 안전하다.
4. 편집한 파일과 실행한 파일이 다르다
"코드를 고쳤는데 결과가 안 바뀐다"의 90%는 다른 폴더의 동명 파일을 실행하고 있는 경우다. 파이썬은 컴파일 과정이 없어서 이런 착각을 잡아 주지 못한다. 의심되면 파일 맨 위에 print("여기가 맞다")를 한 줄 넣고 실행해 본다. 안 찍히면 다른 파일을 보고 있는 것이다.
스스로 확인하기
inventory.py를 고쳐서stock을 0으로 바꾸고 실행하면 몇 줄이 출력되는가? 그리고 그중 마지막 줄은 무엇인가?- 다음 코드는 실행하면 오류가 난다. 어느 줄이 문제이고 이유는 무엇인가?
stock = 0 if stock == 0: print("품절") - 가상환경을 만들고 활성화한 뒤, 그 환경이 실제로 쓰이고 있는지 확인하는 명령은 무엇인가? (힌트: 실행 파일의 경로를 본다)
정답
- 6줄이 출력된다.
if블록의 두 줄이 추가로 실행되기 때문이다. 마지막 줄은출력 끝이다. 이 줄은 들여쓰기가 되어 있지 않아if블록 밖이므로 재고와 무관하게 항상 마지막에 찍힌다. - 3번째 줄이다.
if줄이 콜론으로 끝났으면 다음 줄은 반드시 들여써야 한다. 파이썬은IndentationError: expected an indented block after 'if' statement on line 2를 낸다. 콜론은 곧 "들여쓴 블록이 이어진다"는 약속이다. - 맥·리눅스는
which python3, 윈도우는where python이다. 경로에.venv가 들어 있으면 가상환경이 제대로 잡힌 것이고,/usr/bin/python3처럼 나오면 활성화가 안 된 것이다. 프롬프트의(.venv)표시만 믿지 말고 이렇게 확인하는 습관이 낫다.
다음 단원에서는 이 파일에 쓴 title, price, stock 세 변수를 출발점으로 삼아, 파이썬이 값의 종류를 어떻게 다루는지와 타입을 미리 선언하지 않는 방식의 대가가 무엇인지를 본다.