점프 투 파이썬 - 04

04장 파이썬의 입출력


 

입출력은 프로그래밍 설계와 관련이 있다. 프로그래머는 프로그램을 만들기 전에 어떤 식으로 동작하게 할 것인지 설계를 한다.

이때, 가장 중요한 부분이 바로 입출력이다. 특정 프로그램만 사용하는 함수를 만들 것인지, 모든 프로그램이 공통으로 사용하는 함수를 만들 것인지, 더 나아가 오픈 API로 공개하여 외부 프로그램도 사용할 수 있게 만들 것인지가 모두 입출력과 관련있는 것이다.


 

 

[ 함수 ]

함수란 무엇인가?


한 가지 예를 들어보겠다. 우리가 믹서를 사용하여 주스를 만들려 한다고 가정해보자.

우리는 믹서에 과일을 넣고, 믹서를 켜 과일을 갈아 과일 주스를 만든다.

여기서 믹서에 넣는 과일은 '입력', 과일 주스는 '출력(결과값)'이 되는 것이다.

그렇다면 믹서는 무엇일까. 바로 함수가 되는 것이다.

 

함수라는 것은 이렇게 믹서와 비슷하다. 입력값을 가지고 어떤 일을 수행한 후, 그 결과물을 내어놓는 것이

바로 함수의 기능이기 때문이다.

 

 

함수를 사용하는 이유는 무엇일까?


프로그래밍을 하다 보면 똑같은 내용을 반복해서 작성하는 경우가 종종 있다.

이때가 바로 함수가 필요한 때이다. 즉, 반복되는 코드가 있을 경우, '반복적으로 사용되는 가치 있는 부분'을

한 뭉치로 묶어 '어떤 입력값을 주었을 때 어떤 결과값을 리턴해준다' 라는 식의 함수로 작성하는 것이다.

 

함수를 사용하는 또 다른 이유는 자신이 작성한 프로그램을 기능 단위의 함수로 분리해 놓으면 흐름을 한눈에

볼 수 있기 때문이다. 마치 공장에서 원재료가 여러 공정을 거쳐 하나의 완제품이 되듯이, 프로그램에서도 입력한 

값이 여러 함수를 거치면서 원하는 결괏값을 내는 것을 볼 수 있다. 이렇게 되면 프로그램 흐름도 잘 파악할 수 있고,

오류가 어디에서 발생하는지도 쉽게 알아차릴 수 있다.

 

 

파이썬 함수의 구조


def 함수_이름(매개변수):
	수행할_문장1
    	수행할_문장2

 

def는 함수를 만들 때 사용하는 예약어이며, 함수 이름은 임의로 지정 가능하다. 함수 이름 뒤 괄호 안의 매개변수는

이 함수에 입력으로 전달되는 값을 받는 변수를 말한다.

 

다음 예를 살펴보자.

def add(a, b):
	return a + b

 

위 함수는 다음과 같이 풀이된다.

이 함수의 이름은 add, 입력으로 2개의 값을 받으며, 리턴값(출력값)은
2개의 입력값을 더한 값이다.

 

여기에서 return은 함수의 결과값(리턴값)을 리턴하는 명령어이다.

 

def add(a, b):
	return a + b

a = 3
b = 4
c = add(a, b)
print(c)
7

 

변수 a에 3, b에 4를 대입한 후, add 함수에 a와 b를 입력값으로 넣어준다. 그리고 변수 c에 add 함수의 리턴값을 대입하여

출력하면 값을 확인할 수 있다.

 

 

매개변수와 인수


매개변수(parameter)와 인수(arguments)는 혼용해서 사용되기 때문에 잘 기억해야 한다.

매개변수는 함수에 입력으로 전달된 값을 받는 변수, 인수는 함수를 호출할 때 전달하는 입력값을 의미한다.

 

def add(a, b):		# a, b는 매개변수
	return a + b
    
print(add(3, 4))	# 3, 4는 인수

 

입력값과 리턴값에 따른 함수의 형태


함수는 들어온 입력값을 받은 후 어떤 처리를 하여 적절한 값을 리턴해준다.

함수의 형태는 입력값과 리턴값의 존재 유무에 따라 4가지 유형으로 나뉜다.

 

 

일반적인 함수

def 함수_이름(매개변수):
	수행할_문장
    	...
        return 리턴값
        

# 사용법
리턴값을_받을_변수 = 함수_이름(입력_인수1, 입력_인수2, ...)

 

입력값이 없는 함수

def say():
	return 'Hi'

 

입력값이 없는 함수를 만들기 위해서는 매개변수가 들어가는 () 안에 아무런 값도 없어야 한다. 입력값은 없지만, return 'Hi' 라는

코드를 수행하여 리턴값을 제공한다. 이처럼 입력값이 없고 리턴값만 있는 함수는 다음과 같이 사용한다.

리턴값을_받을_변수 = 함수_이름()

 

리턴값이 없는 함수

def add(a, b):
	print("%d, %d의 합은 %d입니다." % (a, b, a+b))
    
add(3, 4)		# 호출해도 리턴되는 값이 없기 때문에 호출만 한다.
3, 4의 합은 7입니다.

 

즉, 리턴값이 없는 함수는 다음과 같이 사용한다.

함수_이름(입력_인수1, 입력_인수2, ...)

 

여기서 문장을 출력했는데 왜 리턴값이 없는 것인지 의아하게 생각할 수 있다.

print 문은 함수의 구성 요소 중 하나인 '수행할_문장'에 해당하는 부분일 뿐, 리턴값은 없다.

리턴값은 오직 return 명령어로만 돌려받을 수 있다.

 

입력값도, 리턴값도 없는 함수

def say()
	print('Hi')
    
say()
Hi

 

입력 인수를 받는 매개변수도 없고, return 문도 존재하지 않으니 입력값도, 리턴값도 없는 함수이다.

 

즉, 입력값도, 리턴값도 없는 함수는 다음과 같이 사용한다.

함수_이름()

 

 

매개변수를 지정하여 호출하기


함수를 호출할 때 매개변수를 지정할 수도 있다.

def sub(a, b):
	return a - b
    
    
result = sub(a = 7, b = 3)	# a에 7, b에 3을 전달
print(result)

result = sub(b = 5, a = 3)	# b에 5, a에 3을 전달
print(result)
4
-2

 

매개변수를 지정하면 순서에 상관없이 사용할 수 있다는 장점이 있다.

 

 

입력값이 몇 개가 될지 모를 때는 어떻게 해야 할까?


def 함수_이름(*매개변수):
	수행할_문장
    	...

 

일반적으로 볼 수 있는 함수 형태에서 괄호 안의 매개변수 부분이 *매개변수 로 바뀌었다.

 

여러 개의 입력값을 받는 함수 만들기

 def add_many(*args):
 	result = 0
    	for i in args:
    		result += i	# *args에 입력받은 모든 값을 더한다.
   	return result

 

이 함수는 입력값이 몇 개든 상관없다. 매개변수 앞에 *을 붙이면 입력값을 전부 모아 튜플로 만들어주기 때문이다.

*arg는 임의로 정한 변수 이름이다. *pey, *python처럼 아무 이름이나 사용이 가능하다.

 

사용해보면 이렇다.

result = add_many(1, 2, 3)
print(result)

result = add_many(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
print(result)
6
55

 

 

키워드 매개변수, kwargs

 

키워드 매개변수를 사용할 때는 매개변수 앞에 별 2개(**)를 붙인다.

def print_kwargs(**kwargs):
	print(kwargs)

 

print_kwargs는 입력받은 매개변수 kwargs를 출력하는 함수이다.

 

print_kwargs(a = 1)
print_kwargs(name = 'foo', age = 3)
{'a': 1}
{'age': 3, 'name': 'foo'}

 

위 결과값에서 알 수 있듯이, 매개변수 앞에 **을 붙이면 매개변수는 딕셔너리가 되고,

모든 Key=Value 형태의 입력값이

딕셔너리에 저장된다.

 

 

함수의 리턴값은 언제나 하나이다


def add_and_mul(a, b):
	return a + b, a * b
    
result = add_and_mul(3, 4)

 

리턴값은 두 개인데, 리턴값을 받아들이는 변수는 result 하나만 쓰였으므로 오류가 발생할거라 생각할 수 있다.

하지만, 함수의 리턴값은 언제나 하나이기 때문에 오류는 발생하지 않는다. add_and_mul 함수의 리턴값은

(a + b, a * b) 인 튜플값 하나로 리턴된다.

 

따라서 아래와 같은 결과값을 가지게 되는것이다.

result = (7, 12)

 

만약, 이 하나의 튜플 값을 2개의 값으로 분리하여 받고 싶다면 함수를 다음과 같이 출력하면 된다.

result1, result2 = add_and_mul(3, 4)

 

만약, return 문을 두 번 쓰게 되면 어떻게 될까.

2개의 리턴값을 돌려주지 않을까 생각이 들지만, 결과는 그렇지 않다.

def add_and_mul(a, b):
	return a + b
    	return a * b

result = add_and_mul(2, 3)
print(result)
5

 

즉, 함수는 return 문을 만나는 순간, 리턴값을 돌려 준 다음함수를 빠져나가게 된다.

 

 

매개변수에 초깃값 미리 설정하기


def say_myself(name, age, man = True):
	print("나의 이름은 %s 입니다." % name)
    	print("나이는 %d살입니다." % age)
        if man:
        	print("남자입니다.")
        else:
            print("여자입니다.")

 

man = True처럼 미리 값을 넣어주는 것이 바로 함수의 매개변수에 초기값을 설정하는 방법이다.

 

say_myself("박응용", 27)
say_myself("박응용", 27, True)

 

매개변수가 두 개인 위의 코드는 man이라는 변수에 입력값이 없으나, 초기값 True를 갖게 된다.

따라서 동일한 결과를 출력하게 된다.

나의 이름은 박응용입니다.
나이는 27살입니다.
남자입니다.

 

초기값이 설정된 부분을 False로 바꿔 호출하면 출력값은 달라진다.

say_myself("박응선", 27, False)
나의 이름은 박응선입니다.
나이는 27살입니다.
여자입니다.

 

여기서 주의해야 할 점은 초기값이 없는 매개변수는 초기값이 있는 매개변수 뒤에 사용할 수 없다.

따라서 초기값을 설정하고 싶은 매개변수는 항상 뒤쪽에 놓아야 한다.

 

 

함수 안에서 선언한 변수의 효력 범위


a = 1
def vartest(a):
	a += 1
    
vartest(a)
print(a)

 

출력값은 a에 1을 더한 2라고 생각할 수 있지만, 결과값은 1이 된다. 그 이유는 함수에 안에서 사용하는 매개변수는

함수 안에서만 사용하는 '지역변수'일 뿐이기 때문이다. 즉, vartest 함수 안에서의 매개변수 a는 함수 밖의 변수 a와는 전혀 상관이 없다는 뜻이다.

 

 

함수 안에서 함수 밖의 변수를 변경하는 방법


그렇다면 vartest 라는 함수를 사용해서 함수 밖의 변수 a를 1만큼 증가할 수 있는 방법은 없을까?

해결 방법은 2가지가 있다.

 

1. return 사용하기

# vartest_return.py
a = 1 
def vartest(a): 
	a = a +1 
	return a

a = vartest(a) 
print(a)

 

첫 번째 방법은 함수 밖의 변수 a에 vartest의 결과값을 저장하는 방법이다.

하지만, 여기서도 vartest 함수 안의 a 매개변수는 함수 밖의 a와는 다른 것이다.

 

2. global 명령어 사용하기

a = 1 
def vartest(): 
	global a 
	a = a+1

vartest() 
print(a)

 

두 번째 방법은 global 명령어를 사용하는 것이다.

global a 는 함수 안에서 함수 밖의 변수 a를 직접 사용하겠다는 말이다. 하지만 프로그래밍을 할 떄 gloabl 명령어는 사용하지

않는 편이 좋다. 함수는 독립적으로 존재하는 것이 좋기 때문이다. 외부 변수에 종속적인 함수는 그다지 좋은 함수가 아니다.

따라서 되도록이면 global 명령어보다는 첫 번째 방법을 사용하는 것을 권한다.

 

 

lambda 예약어


lambda는 함수를 생성할 때 사용하는 예약어로, def와 동일한 역할을 한다. 보통 함수를 한  줄로 간결하게 만들 때 사용한다.

우리는 '람다'라고 읽고, def를 사용해야 할 정도로 복잡하지 않거나 def를 사용할 수 없는 곳에 주로 쓰인다.

함수_이름 = lambda 매개변수1, 매개변수2, ... : 매개변수를_이용한_표현식

 

예시는 다음과 같다.

add = lambda a, b: a + b
result = add(3, 4)
print(result)
7

 

lambda로 만든 함수는 return 명령어가 없어도 표현식의 결과값을 리턴한다.

 

 


[ 사용자 입출력 ]

사용자 입력 활용하기


사용자가 입력한 값을 어떤 변수에 대입하고 싶을 때는 어떻게 해야 할까?

 

 

input 사용하기

a = input()

print(a)
Life is too short, you need python
'Life is too short, you need python'

 

input은 사용자가 키보드로 입력한 모든 것을 문자열로 저장한다.

 

 

 

프롬프트를 띄워 사용자 입력받기

 

사용자에게 입력받을 때 '숫자를 입력하세요'나 '이름을 입력하세요'라는 안내 문구 또는 질문을 보여주고 싶을 때가 있다.

그럴 때는 input()의 괄호 안에 안내 문구를 입력하여 프롬프트를 띄워주면 된다.

 

input("안내_문구")

 

 

print 자세히 알기


큰따옴표로 둘러싸인 문자열은 + 연산과 동일하다.

print("life" "is" "too short")  # 1번
print("life"+"is"+"too short")  # 2번
lifeistoo short
lifeistoo short

 

따옴표로 둘러싸인 문자열을 연속해서 쓰면 + 연산을 한 것과 같다.

 

 

문자열 띄어쓰기는 쉼표로 한다

print("life", "is", "too short")
life is too short

 

쉼표(,)를 사용하면 문자열을 띄어 쓸 수 있다.

 

 

한 줄에 결과값 출력하기

 

한 줄에 결과값을 계속 이어서 출력하려면 매개변수 end를 사용해 끝 문자를 지정해야 한다.

for i in range(10):
	print(i, end=' ')
0 1 2 3 4 5 6 7 8 9

 

  • end 매개변수의 초기값은 줄바꿈(\n) 문자이다.

 

[ 파일 읽고 쓰기 ]

파일 생성하기

f = open("새파일.txt, 'w')
f.close()

 

프로그램을 실행한 디렉터리에 새로운 파일이 하나 생성됐다.

 

파일을 생성하기 위해 파이썬 내장 함수 open을 사용했다. open 함수는 다음과 같이 '파일 이름'과 '파일 열기 모드'를 

입력값으로 받고 결과값으로 파일 객체를 리턴한다.

파일_객체 = open(파일_이름, 파일_열기_모드)

 

파일 열기 모드에는 다음과 같은 것들이 있다.

파일 열기 모드 설명
r 읽기 모드 : 파일을 읽기만 할 때 사용한다.
w 쓰기 모드 : 파일에 내용을 쓸 때 사용한다.
추가 모드 : 파일의 마지막에 새로운 내용을 추가할 때 사용한다.

 

파일을 쓰기 모드로 열면 해당 파일이 이미 존재할 경우 원래 있던 내용이 모두 사라지고, 해당 파일이 존재하지 않으면 새로운 파일이 생성된다.

 

만약, '새파일.txt' 파일을 특정 디렉터리에 생성하고 싶다면 다음과 같이 작성해야 한다.

드라이브와 경로는 자신의 컴퓨터 환경에 맞게 지정하면 된다.

f = open("드라이브:/경로/새파일.txt", 'w')
f.close()

 

f.close()는 열려있는 파일 객체를 닫아주는 역할을 한다. 이 문장은 생략이 가능하다.

프로그램을 종료할 때 파이썬 프로그램이 열려있는 파일의 객체를 자동으로 닫아주기 때문이다.

하지만, 쓰기모드로 열었던 파일을 닫지 않고 사용하려고 하면 오류가 발생하기 때문에 close()를 사용해서

직접 닫아주는 것이 좋다.

 

 

파일을 쓰기 모드로 열어 내용 쓰기


f = open("드라이브:/경로/새파일.txt", 'w')
for i in range(1, 11):
	data = "%d번째 줄입니다.\n" % i
	f.write(data)
f.close()

 

생성된 파일을 열면 다음과 같이 저장되어 있다.

 

 

파일을 읽는 여러 가지 방법


readline 함수 이용하기

f = open("드라이브:/경로/새파일.txt", 'r')
line = f.readline()
print(line)
f.close()

 

위는 '새파일.txt' 파일을 읽기 모드로 연 후 readline()을 사용해서 파일의 첫 번째 줄을 읽어 출력하는 예제이다.

실행했을 때 새파일.txt 파일의 가장 첫 번째 줄이 화면에 출력될 것이다.

1번째 줄입니다.

 

만약 모든 줄을 읽어 출력하고 싶다면 다음과 같이 작성하면 된다.

f = open("드라이브:/경로/새파일.txt", 'r')
while True:
	line = f.readline()
	if not line: break
	print(line)
f.close()

 

한 줄씩 읽어 출력하기 때문에 \n 문자가 있는 빈 줄도 같이 출력된다.

 

 

readlines 함수 사용하기

f = open("드라이브:/경로/새파일.txt", 'r')
lines = f.readlines()
for line in lines:
	print(line)
f.close()

 

readlines 함수는 파일의 모든 줄을 읽어서 각각의 줄을 요소로 가지는 리스트를 리턴한다.

 

더보기

줄 바꿈(\n) 문자 제거하기

 

파일을 읽을 때 줄 끝의 줄 바꿈(\n) 문자를 제거하고 사용해야 할 경우가 생긴다.

그럴 땐 strip 함수를 사용하면 된다.

 

f = open("드라이브:/경로/새파일.txt", 'r')
lines = f.readlines()
for line in lines:
	line = line.strip()  # 줄 끝의 줄 바꿈 문자를 제거
	print(line)
f.close()

 

read 함수 사용하기

f = open("드라이브:/경로/새파일.txt", 'r')
data = f.read()
print(data)
f.close()

 

f.read() 함수는 파일의 내용 전체를 문자열로 리턴한다. 따라서 data는 파일의 전체 내용이다.

 

 

파일 객체를 for 문과 함께 사용하기

f = open("드라이브:/경로/새파일.txt", 'r')
for line in f:
    print(line)
f.close()

파일 객체(f)는 기본적으로 위와 같이 for 문과 함께 사용하여 파일을 줄 단위로 읽을 수 있다.

 

파일에 새로운 내용 추가하기


쓰기 모드('w')로 파일을 열 때, 이미 존재하는 파일이라면 그 파일의 내용은 모두 사라진다.

하지만, 원래의 파일에 새로운 값만 추가해야 할 경우도 있다. 그럴 땐 파일을 추가 모드('a') 로 열면 된다.

f = open("드라이브:/경로/새파일.txt",'a')
for i in range(11, 20):
    data = "%d번째 줄입니다.\n" % i
    f.write(data)
f.close()

 

따라서 파일을 열어보면 기존 내용이 사라지지 않고 새로운 내용이 추가된 것을 확인할 수 있다.

 

with 문과 함께 사용하기


f = open("foo.txt", 'w')
f.write("Life is too short, you need python")
f.close()

 

파일을 열면(open) 항상 닫아(close) 주어야 한다. 하지만 직접 적다보면 잊어버리기도 한다.

때문에 자동으로 해주는 것이 없을까 하고 고민하게 된다. 이때, 파이썬의 with 문을 사용하면 된다.

with open("foo.txt", "w") as f:
	f.write("Life is too short, you need python")

 

위와 같이 with 문을 사용하게 되면, with 블록(안의 문장)을 벗어나는 순간, 열린 파일 객체 f가 자동으로 닫히게 된다.


 

[ 프로그램의 입출력 ]

sys 모듈 사용하기


파이썬에서는 sys 모듈을 사용하여 프로그램에 인수를 전달할 수 있다.

파이썬에서 모듈을 사용하기 위해서는 import 명령어를 사용해야 한다.

import sys

args = sys.argv[1:]
for i in args:
	print(i)

 

위는 프로그램 실행 시 전달받은 인수를 for 문을 사용해 차례대로 하나씩 출력하는 예이다.

sys 모듈의 argv는 프로그램 실행 시 전달된 인수를 의미한다.

 

이 프로그램을 바탕화면에 저장하고 인수를 전달하여 실행하면 다음과 같은 결과를 볼 수 있다.

C:\Users\사용자\Desktop>sys1.py aaa bbb ccc
aaa
bbb
ccc

'Python > ' 카테고리의 다른 글

점프 투 파이썬 - 05  (0) 2023.11.12
점프 투 파이썬 - 03  (1) 2023.11.12
점프 투 파이썬 - 02  (1) 2023.11.09
점프 투 파이썬 - 01  (0) 2023.11.08