티스토리 뷰
표준입력과 input 함수
지난 글에서 파이썬에서 텍스트 파일을 액세스할 때 파일 핸들러를 만들어서 사용한다고 했고, 파일 핸들러는 내부적으로 TextIOWrapper
라는 버퍼 객체라고 했다.
input()
내장함수 역시 TextIOWrapper
를 사용한다. 대신 열리는 것이 디스크 상의 파일이 아니라 쉘이 제공하는 표준입력이다. TextIOWrapper(name="<stdin>")
과 같은 식으로 만들어지는 버퍼가 있고, 이 버퍼는 표준입력을 파일로 간주하고 한 줄씩 읽은 결과를 리턴한다. 즉 이 말은 우리는 input()
함수 자체가 파일의 readline()
과 비슷하게 동작한다는 것인데, 쉘의 입출력 특성을 사용하여, input()
함수만으로 파일을 읽어들이는 것이 가능하다는 점 시사한다.
다만 차이가 있다면 파일 핸들러에서 readline()
을 사용하면 개행 혹은 EOF를 만날 때까지 읽은 값을 리턴하는데, input()
함수는 EOF
를 만나면 EOFError
예외를 일으킨다는 점이다.
따라서 우리는 입력된 문자열을 받아서 처리한 후 다시 결과 문자열을 되돌려주는 타입의 함수를 이용해서 표준입력(input)과 표준출력(print)을 연결하는 interact()
라는 함수를 다음과 같이 작성할 수 있다.
def interact(fn):
'''
fn은 (str) -> str 타입의 함수이며
input()으로 받아온 문자열을 fn을 통해 처리하고 그 결과를 print()로 출력한다.
즉 프로세싱 함수를 받아서 표준입력과 표준출력 사이를 연결한다.
'''
try:
while True:
print(fn(input()))
except EOFError:
pass
지난 시간에 각 줄의 숫자들의 합과 평균을 구하는 함수를 다시 생각해보자.
def sum_and_avg(ns):
s = sum(ns)
return s, s / len(ns)
## 각 줄을 처리하는 함수
def process(line):
return '{0} {1:0.2f}'.format(*sum_and_avg([int(n) for n in line.split()]))
이제 최종 프로그램 실행 코드는 다음과 같이 완성된다.
if __name__ == '__main__':
interact(process)
자, 이 프로그램을 실행하면 어떤 식으로 동작하는지 살펴보자.
interact
함수가process
함수를 인자로 받고 실행된다.input()
이 호출되어 입력을 기다린다.- 공백으로 구분된 일련의 정수값들을 입력하면 그 정수값들의 합과 평균(소수점 둘째자리까지)을 계산하여 출력한다.
- EOF가 입력되면 종료된다. (macOS에서는 ctrl+D, 윈도에서는 ctrl+Z) 그렇지 않으면 2번으로 돌아가서 이를 반복한다.
그런데 지난 시간에서도 많은 입력을 처리하기 위해서는 파일을 사용한다고 했다. 이 프로그램을 어떻게 만들 수 있을까? 바로 "리다이렉트(redirect)"를 이용하는 것이다. 쉘에서 실행되는 프로그램이 실행 중에 키보드로 입력을 받는다면, 이는 시스템의 표준입력을 이용하는 것이고, 터미널 상에서 기본적인 표준입력은 키보드에 해당한다.
하지만 다른 파일을 리다이렉트를 통해서 표준입력을 대체하도록 하면, 파일의 각 행을 한 번의 키보드 입력 (문자찍고 엔터누를때까지)으로 인식하게 된다.
따라서 여기서 만든 파일을 sumAgv.py
라 저장하고 테스트해보도록 하자. 먼저 샘플 데이터를 생성하자.
import random
def make_ns(k=1):
ns = [random.randrange(1, 100) for _ in range(k)]
return ' '.join(str(x) for x in ns)
with open('data.txt', 'w') as f:
data = '\n'.join(make_ns(8) for _ in range(100))
f.writelines(data)
위 코드를 실행해서 100줄짜리 샘플데이터를 만든 후 쉘에서 다음과 같이 실행한다.
$ python sumAvg.py < data.txt
그러면 계산된 결과 100줄이 죽 표시될 것이다. 만약 그 결과를 다른 파일로 저장하고 싶다면? 표준 출력에 대해서도 리다이렉트를 수행한다.
$ python sumAvg.py < data.txt > result.txt
결과는 아무것도 출력되지 않는다. 대신에 현재 디렉토리에 result.txt
라는 파일이 생성되어 있을 것이고, 이 파일을 열어보면 계산 결과가 들어있을 것이다.
이와같이 쉘의 표준입출력과 리다이렉트 개념을 이용하면 파일 액세스를 간단하게 input()
, print()
로 대체할 수 있다.
'파이썬 how to' 카테고리의 다른 글
그리드 형식의 값을 다루는 방법 (0) | 2017.11.13 |
---|---|
리스트에서 중복된 원소를 제거하기 (1) | 2017.11.07 |
파일입출력 : 파일을 읽고 쓰는 방법 (0) | 2017.10.28 |
CSV 파일 다루기 (0) | 2017.10.10 |
raw 파일에 담긴 자료를 추출하여 가공하기 (0) | 2017.09.15 |
- Total
- Today
- Yesterday
- Lambda
- mutability
- 우분투
- leapYear
- 단어 빈도수
- Python
- 함수형
- 이중리스트를 사용하지 않기
- 튜플언패킹
- 정렬키
- 파이썬
- dict
- sorted
- python list
- globals()
- 리스트
- 정렬기준
- iterable
- 복수기준정렬
- 파이썬노트북
- locals()
- short_circuit
- 변경가능
- 리눅스
- 사전
- jupyter-notebook
- 표준입력
- 파일입출력
- 반복자
- ipython-notebook
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |