본문 바로가기
C.W.K.
Stream
Lesson 03 of 07 · published

REPL을 계산기보다 잘 쓰는 법

~18 min · repl, ipython, 히스토리, 자동완성, underscore, exec-eval

Level 0호기심
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete

묻고 바로 답을 받는 자리

REPL은 코드를 읽고(Read), 계산하고(Evaluate), 출력하고(Print), 다시 기다리는(Loop) 대화형 환경이야. 한두 줄을 시험하고 객체를 살펴보기에는 최고지만, 오래 남길 작업은 파일로 옮겨야 해.

기억과 도움말을 써

위·아래 화살표로 이전 입력을 불러오고, 최근 결과는 _로 다시 쓸 수 있어. help(obj)는 사용법을, dir(obj)는 접근 가능한 이름을 보여줘. 모르는 객체를 만났을 때 검색창보다 먼저 객체 자체에 물어볼 수 있는 셈이야.

끝난 프로그램 위에서 계속 살펴보기

python -i script.py는 파일을 실행한 뒤 그 상태를 남긴 채 REPL로 들어가. 계산 결과와 변수들을 그대로 검사할 수 있어. Python 3.13의 기본 REPL은 여러 줄 편집과 색 표시가 좋아졌고, IPython과 bpython은 자동 완성·기록·풍부한 출력 같은 편의를 더해.

문자열을 코드로 실행하지 마

evalexec는 문자열을 Python 코드로 실행하므로 외부 입력에 쓰면 곧바로 코드 실행 권한을 내주는 셈이야. ast.literal_eval은 리터럴만 허용해 범위가 좁지만, 큰 입력이 자원을 소모할 수 있다는 점까지 사라지는 건 아니야.

원칙: REPL은 가설을 빠르게 확인하는 실험대야. 확인한 코드는 재현할 수 있도록 파일과 테스트로 옮겨.

Code

기록, 자동 완성, 최근 결과 활용하기·python
>>> import string
>>> string.<TAB>           # Tab 누름 — string 모듈의 모든 이름 보여줌
string.ascii_letters     string.ascii_lowercase   string.ascii_uppercase
string.capwords(         string.digits            string.hexdigits
...

>>> 2 + 2
4
>>> _ * 10                 # _ 가 마지막 결과를 들고 있음
40
>>> _ + 5                  # 매번 업데이트
45

>>> # 위 화살표 — 직전 줄 다시 떠, 편집 가능 상태.
>>> # 시도해봐 — 뭔가 입력, 위, 편집, Enter.
help와 dir로 객체에 직접 묻기·python
>>> dir("hello")
['__add__', '__class__', ..., 'capitalize', 'casefold', 'center',
 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format',
 'format_map', 'index', 'isalnum', ..., 'upper', 'zfill']

>>> help(str.upper)
Help on method_descriptor:

upper(self, /)
    Return a copy of the string converted to uppercase.

>>> # 인자 없는 help() → full 대화형 docs.
>>> # 어떤 help 화면이든 q 로 빠져나옴.
스크립트 실행 뒤 REPL로 이어 보기·bash
# my_buggy_script.py
x = [1, 2, 3]
y = [n * 2 for n in x]
z = y[10]    # IndexError: list index out of range

$ python -i my_buggy_script.py
Traceback (most recent call last):
  File "my_buggy_script.py", line 3, in <module>
    z = y[10]
        ~^^^^
IndexError: list index out of range
>>> x          # 스크립트가 정의한 모든 이름 살아있음
[1, 2, 3]
>>> y
[2, 4, 6]
>>> len(y)     # 아 — 3개뿐인데 10 인덱싱이 말이 안 됐어
3
>>> # 들여다보기, 스크립트 고치기, python -i 로 다시.
IPython에서 달라지는 점·python
$ pip install ipython
$ ipython

In [1]: %timeit sum(range(1000))     # magic command — 마이크로 벤치마크
8.42 µs ± 50.1 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [2]: %run myscript.py             # 현재 namespace 에서 파일 실행

In [3]: import requests
In [4]: r = requests.get("https://api.github.com")
In [5]: r.<TAB>                       # ipython 의 자동완성이 더 풍부

In [6]: r?                            # ?  하나 — docstring
In [7]: r??                           # ?  둘 — 소스 코드

In [8]: history                       # 전체 세션 히스토리, 줄 번호 포함
외부 입력을 eval이나 exec에 넘기지 않기·python
# 위험 — 사용자 입력에 *절대* 이렇게 하지 마.
user_expr = input("수식: ")
result = eval(user_expr)              # 임의 코드 실행

# Python literal만 받아야 할 때:
import ast
literal_text = input("Python literal: ")  # 예: [1, 2, 3]
if len(literal_text) > 10_000:
    raise ValueError("입력이 너무 큼")
value = ast.literal_eval(literal_text) # 연산식·함수 호출은 평가하지 않음

# JSON 입력이면 JSON parser를 써:
import json
data = json.loads(input("JSON: "))

External links

Exercise

IPython을 사용할 환경에 설치하고 지난 수업의 코드 세 덩어리를 다시 실행해봐. 기본 REPL과 입력 기록, 자동 출력, 색 표시가 어떻게 다른지 적어. 이어서 print?len??를 실행해 각각 어떤 정보를 보여주는지 비교해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.