함수(function)는 여러 줄의 일을 묶어 이름을 붙여 둔 것입니다. def로 만들어 두고 이름 뒤에 괄호를 붙여 부르면, 새 칸이 생겨 그 안에서 일을 하고 return으로 값 하나를 돌려줍니다.
같은 계산을 여러 곳에서 하려면 같은 줄을 되풀이해 쓰고, 계산이 바뀌면 그 줄을 모두 고쳐야 합니다. 함수로 만들어 두면 부를 때마다 같은 일을 하고 고칠 곳도 하나입니다. 지금까지 쓴 print·len·input도 파이썬이 만들어 둔 함수입니다.
이 레슨에서는 함수를 부를 때 일어나는 일을 규칙 5로 세웁니다.
이 단원(함수)을 이미 안다면 단원 연습 문제부터 풀고 틀린 레슨만 보세요.
1부르면 새 칸이 생기고, return이 값을 돌려준다
그림의 코드입니다.
def double(n):
return n * 2
x = double(4)
1번 줄은 함수를 만들어 이름 double을 붙입니다. def 줄과 그 아래 들여 쓴 덩어리를 함께 함수 정의(definition)라 하고, 들여 쓴 덩어리를 함수 몸(body)이라 합니다. 몸은 만들 때 실행하지 않아서, 실행은 2번 줄을 건너 5번 줄로 갑니다.
5번 줄은 오른쪽 double(4)부터 계산합니다(규칙 2). 함수 이름 뒤에 괄호를 붙이면 그 함수를 부릅니다. 부르면 새 칸이 생기고, 괄호 안의 이름 n이 넘긴 값 4에 붙습니다. n처럼 함수를 만들 때 괄호 안에 적는 이름을 매개변수(parameter)라고 합니다.
그림의 칸 머리 'double 호출'이 이 칸이고, 함수를 부르는 일을 자료에 따라 호출(call)이라고도 합니다. 맨 위 '전역'(global) 칸은 파일 맨 바깥 줄의 이름이 있는 칸입니다.
그다음 함수 몸의 2번 줄이 실행됩니다. return n * 2는 n * 2를 계산한 8을 부른 자리인 double(4) 자리로 돌려줍니다. 돌려주면 칸이 사라지고, 5번 줄은 돌려받은 8에 이름 x를 붙입니다. n이 붙어 있던 4는 '가리키는 이름 없음'으로 남습니다.
이 코드는 아무것도 찍지 않습니다. x가 붙은 값을 보려면 print(x)를 더합니다.
def double(n):
return n * 2
x = double(4)
print(x)
8이번에는 return 없이 print만 하는 함수입니다. 무엇이 찍힐까요? 답을 정한 뒤 펼쳐 보세요.
def f():
print(3)
x = f()
print(x)
실행 결과 보기
3
None예상과 다르면 그곳이 배울 곳입니다.
5번 줄이 f를 부르면 2번 줄 print(3)이 화면에 3을 씁니다. print는 화면에 쓸 뿐 부른 자리로 값을 돌려주지 않고, f의 몸에는 return이 없습니다. return 없이 몸이 끝나면 함수는 돌려줄 값이 없다는 뜻의 값 None을 돌려줍니다. 그래서 x는 None에 붙고, 6번 줄이 None을 찍습니다.
3 한 줄로 끝나거나(None 없이) 3이 두 줄 찍힌다고 예상했다면, 화면에 찍는 것과 값을 돌려주는 것을 같은 일로 본 것입니다.
double과 f를 견주면 함수를 부를 때 일어나는 일이 셋으로 모입니다.
규칙 5. 함수를 부르면 새 칸이 생겨 그 안에서 이름이 만들어집니다.
return은 값 하나를 부른 자리에 돌려주고 칸을 없앱니다.None).
2def는 만들기만 하고, 부를 때마다 몸이 실행된다
함수 몸은 def 줄을 지날 때가 아니라 부를 때마다 실행됩니다.
def greet():
print('어서 오세요')
print('문을 엽니다')
greet()
greet()
print('끝')
문을 엽니다
어서 오세요
어서 오세요
끝1번 줄은 함수를 만들기만 해 아무것도 찍지 않습니다. 5번 줄이 먼저 찍고, 6번 줄과 7번 줄이 부를 때마다 새 칸에서 2번 줄이 실행됩니다. 몸이 끝나면 부른 줄로 돌아와 그다음 줄로 갑니다.
부르는 줄이 def 줄보다 위에 있으면 오류가 납니다.
greet()
def greet():
print('어서 오세요')
Traceback (most recent call last): File "main.py", line 1, in <module> greet() ^^^^^NameError: name 'greet' is not defined맨 아래 줄은 greet라는 이름이 없다는 뜻입니다. 위에서 아래로 실행하므로(규칙 1), 1번 줄을 실행할 때는 4번 줄의 def가 아직 greet를 붙이지 않았습니다. 부르는 줄을 함수 정의 아래로 옮기면 됩니다.
예제
함수로 감싸기 — 잔 수로 값 구하기
잔 수를 받아 커피 값을 돌려주는 함수를 하위 목표 셋으로 나눠 썼습니다.
# 1. 받을 값 정하기
def price(cups):
# 2. 계산하기
won = cups * 4000
# 3. 돌려주기
return won
print(price(2))
print(price(3))
8000
12000받을 값(잔 수)을 매개변수 cups로 정하고, 몸에서 계산하고, return으로 돌려줍니다. won은 함수 칸 안의 이름입니다.
9번 줄은 돌려받은 8000을 print에 넘겨 찍고, 10번 줄은 새 칸에서 cups를 3에 붙여 다시 계산합니다.
자주 틀리는 곳
틀린 생각: 함수 안에서 print로 찍은 값이 함수를 부른 결과로 돌아온다.
화면에 값이 보이니 함수가 그 값을 내놓은 것처럼 여기게 됩니다. 화면에 쓰는 일과 부른 자리로 값을 돌려주는 일은 다릅니다.
def f():
print(3)
print(f())
3
None3은 2번 줄이 화면에 쓴 것입니다. 5번 줄의 print가 찍은 None은 f가 돌려준 값입니다.
맞는 규칙: print는 화면에 쓸 뿐 값을 돌려주지 않고, return이 없는 함수는 None을 돌려줍니다. 값을 돌려받으려면 return을 씁니다(규칙 5).
틀린 생각: 괄호 없이 함수 이름만 써도 함수가 실행된다.
이름이 함수를 나타내니, 이름만 적어도 그 일을 할 것처럼 보입니다. 이름은 함수를 가리킬 뿐이고, 함수를 부르는 것은 괄호입니다.
def greet():
print('어서 오세요')
greet
print('끝')
끝5번 줄은 이름 greet가 가리키는 함수를 꺼내기만 하고 부르지 않아, '어서 오세요'가 찍히지 않습니다. print(len)이 <built-in function len>을 찍는 것도 이름 len이 함수 그 자체를 가리키기 때문입니다.
맞는 규칙: 함수 이름은 함수를 가리킬 뿐이라 이름만 쓰면 아무 일도 일어나지 않습니다. 부르려면 greet()처럼 이름 뒤에 괄호를 붙입니다(규칙 5).
확인 문제
1. 2절 첫 코드에서 5번 줄과 6번 줄의 차례를 바꿨습니다. 무엇이 찍힐까요? 마지막 줄까지 글자 그대로 쓰세요.
def greet():
print('어서 오세요')
greet()
print('문을 엽니다')
greet()
print('끝')
힌트
5번 줄부터 차례로 따라가며, greet() 줄에서는 2번 줄로 들어갔다가 돌아와 다음 줄로 갑니다.
정답
모두 4줄입니다.
어서 오세요
문을 엽니다
어서 오세요
끝1번 줄은 함수를 만들기만 합니다. 5번 줄과 7번 줄이 부를 때마다 2번 줄이 '어서 오세요'를 찍고, 그 사이에 6번 줄이 '문을 엽니다'를 찍습니다.
흔한 오답은 맨 위에 '어서 오세요'가 한 줄 더 붙은 다섯 줄입니다. def 줄을 지날 때도 몸이 실행된다고 본 것입니다. 몸은 부를 때만 실행됩니다(규칙 5).
2. 12000이 찍히도록 아래 네 줄을 위에서 아래로 놓으세요. 들여쓰기는 맞게 적었고, 빈 줄은 생각하지 않습니다.
㉠ print(total)
㉡ return cups * 4000
㉢ total = price(3)
㉣ def price(cups):
힌트
놓아 본 차례대로 1번 줄부터 실행하며, 줄마다 그 줄이 읽는 이름이 이미 붙어 있는지 봅니다.
놓은 뒤 물음
놓은 차례에서 ㉢이 ㉣보다 아래에 오는 까닭은 무엇일까요?
- ① ㉣이 먼저 실행되어 이름 price가 함수에 붙어 있어야 ㉢이 price를 부를 수 있기 때문
- ② ㉣을 지날 때 몸 ㉡이 실행되어, ㉢의 total이 붙을 값이 미리 만들어지기 때문
- ③ 파이썬은
def를 어디에 두든 먼저 읽어 두므로, ㉢이 ㉠보다 위이기만 하면 되기 때문
정답
㉣ ㉡ ㉢ ㉠ 차례이고, 까닭은 ①입니다.
def price(cups):
return cups * 4000
total = price(3)
print(total)12000바꿔도 되는 줄은 없습니다. 넷의 차례 24가지를 모두 돌려 보면 12000을 찍는 것은 이 차례 하나입니다.
- ②
def줄은 함수를 만들어 이름을 붙일 뿐이고, 몸 ㉡은 ㉢이 부를 때 실행됩니다(규칙 5). - ③ 파이썬은 위에서 아래로 한 줄씩 실행합니다. ㉢을 ㉣보다 위에 두면 그 줄을 실행할 때 price가 아직 없어
NameError가 납니다(규칙 1).
3. 시험 점수에 5점을 더하는 함수 둘입니다. 무엇이 찍힐까요? 마지막 줄까지 글자 그대로 쓰세요.
def plus(score):
return score + 5
def show(score):
print(score + 5)
a = plus(90)
b = show(90)
print(a, b)
힌트
9번 줄과 10번 줄에서 a와 b가 각각 무엇에 붙는지, 그 사이 화면에 무엇이 찍히는지 차례로 적어 봅니다.
정답
모두 2줄입니다.
95
95 None9번 줄은 plus가 돌려준 95에 a를 붙이고, 화면에는 아무것도 찍지 않습니다. 10번 줄이 show를 부르면 6번 줄이 화면에 95를 찍고, return이 없는 show는 None을 돌려줘 b가 None에 붙습니다. 11번 줄은 95 None을 찍습니다.
흔한 오답은 95 95 한 줄입니다. show가 찍은 95가 b에 돌아온다고 본 것입니다(찍는 것과 돌려주는 것이 같다는 생각). print는 화면에 쓰고 None을 돌려줍니다(규칙 5). 95 None 한 줄만 쓴 답은 10번 줄이 show를 부르는 동안 6번 줄이 찍는 95를 빠뜨린 것입니다.
5번 줄을 x = double(double(4))로 바꾸면 6번 줄이 무엇을 찍는지 봅니다.
처음 펼 때 약 6MB를 받습니다.컴퓨터에서 해 보기
파이썬 3.14. Tab을 누르면 다음 단추나 칸으로 갑니다. 들여쓰기는 빈칸 네 개입니다. Enter는 앞줄 들여쓰기를 잇고, 콜론 뒤에서는 한 단계 더 들여 씁니다. Ctrl+Enter로 실행합니다.
'실행'을 누르면 여기에 나옵니다.
여기서 쓴 코드 · 내 예상은 저장하지도 운영자에게 보내지도 않습니다. 페이지를 새로 열면 처음 코드입니다.