목차
- 함수란?
- 함수를 사용하는 이유
- 파이썬의 기본 함수 구조
- 입력값과 결과값에 따른 함수 형태
- 입력값이 몇 개가 될지 모를 때
- 함수의 결과값은 언제나 하나다
- 입력 인수에 초기값 미리 설정
- 함수 안에서 선언된 변수의 효력 범위
함수
1. 함수란?
파이썬을 포함한 프로그래밍 언어에서 말하는 함수와 학창 시절 수학에서 배웠던 함수는 비슷하면서도 다르다.
프로그래밍에서의 함수는 어떤 특정한 일을 수행하는 독립적인 단위를 뜻하며, 입력값을 가지고 어떤 특정한 일을 수행한 다음 그 결과물을 보여주는 것이 함수가 하는 일이다. 프로그래밍에서 함수는 정말 중요한 부분이다. (공부 중인 책 '점프 투 파이썬'에서는 함수를 믹서기와 같다고 한다. 과일은 '입력'이 되고 믹서기는 '함수', 과일 주스는 '출력'이 된다.)
2. 함수를 사용하는 이유
프로그래밍 언어를 사용해 프로그래밍을 하다보면 분명 반복적으로 작성되고 사용되는 부분이 있다고 한다. 이때 함수가 필요한데 반복적으로 사용되는 부분을 한 뭉치로 묶어서 사용할 수 있다.
그리고 이 함수를 통해 자신이 만든 프로그램의 흐름을 파악하기 쉽다. 그렇기 때문에 에러가 발생하는 부분의 파악 등도 쉽게 할 수 있다.
3. 파이썬의 기본 함수 구조
파이썬에서는 함수를 만들 때 아래와 같은 기본적인 구조로 구성된다.
def 함수명(입력 인수):
수행할 문장1
수행할 문장2
...
먼저, def라는 예약어를 사용한다. 함수명은 프로그래밍을 하는 사람이 임의로 만들 수 있다. 함수명 뒤에 위치한 입력 인수는 이 함수에 입력될 값이라는 뜻이다. 이렇게 기본 적으로 함수를 정의한 다음 앞에서 배웠던 if, while, for을 활용해 함수에서 수행할 문장을 입력한다.
다음 예를 통해 쉽게 이해할 수 있다.
>>> def sum(a, b): <---- 함수명 sum이고, 입력 인수 a와 b인 함수
... return a + b <---- 함수의 결과값을 a + b로 돌려주라는 명령
...
>>> a = 3 <---- 입력 인수 a는 3
>>> b = 4 <---- 입력 인수 b는 4
>>> c = sum(a, b) <---- sum(3, 4)의 리턴값을 c에 대입
>>> print(c)
7
위 소스코드를 풀이하면 "이 함수의 이름은 sum이고, 입력 인수로 a와 b 2개의 입력값을 받는다. 그리고 결과값은 2개의 입력값을 더한 값이다."
4. 입력값과 결과값에 따른 함수 형태
함수의 형태는 입력값과 결과값의 존재 유무에 따라 4가지의 유형으로 나뉜다. 대괄호 [ ]안에 각 형태별 사용 방법도 잘 기억하자.
1. 일반적인 함수 [결과값을 받을 변수 = 함수명(입력 인수1, 입력 인수2, ..., 입력인수 N]
- 입력값이 있고, 결과값이 있는 함수
2. 입력값이 없는 함수 [결과값을 받을 변수 = 함수명()]
- 입력값이 없고, 결과값만 있는 함수
3. 결과값이 없는 함수 [함수명(입력 인수1, 입력 인수2, ..., 입력인수 N]
- return명령어(결과값)가 없는 함수
4. 입력값과 결과값 둘 다 없는 함수 [함수명()]
- 입력인수를 받을 곳과 return 명령어도 없는 함수
앞으로 프로그래밍을 할 때 가장 많이 사용하는 형태는 일반적인 함수의 형태다. 설명한 각 유형별 함수 형태의 예시는 아래와 같다. 위에서 설명한 4가지 형태의 함수 유형을 잘 기억하면서 보자.
# 일반적인 함수
>>> a = sum(3, 4)
>>> def sum(a, b):
... result = a + b
... return result <---- a + b의 결과값 리턴
...
>>>
>>> a = sum(3, 4) <---- 함수의 사용방법
>>> print(a)
7
# 입력값이 없는 함수
>>> def say():
... return 'Hi'
...
>>> a = say() <---- 괄호 안에 입력값이 없어야 결과값 출력
>>> print(a)
Hi
# 결과값이 없는 함수
>>> def sum(a, b):
... print("{0} plus {1} is {2}." .format(a, b, a + b))
...
>>> sum(3, 4) <---- return(결과값)이 없기 때문에 함수명 직접 입력
3 plus 4 is 7.
# 입력값과 결과값 둘 다 없는 함수
>>> def say(): <---- 입력값 X
... print("Hi")
...
>>> say() <---- return(결과값)이 없기 때문에 함수명 직접 입력
Hi
위 소스코드 중 '결과값이 없는 함수'에서 '3 plus 4 is 7.'이라는 문장이 출력됬다. 진짜 결과값이 없을까?
위에서 print를 통해 문장이 출력됬다. 이 print문은 함수의 구성요소 중 하나인 '수행할 문장'에 해당하는 부분일 뿐이다. 결과값은 return을 통해서만 돌려받을 수 있다.
>>> a = sum(3, 4)
>>> print(a)
None
결과값 출력을 위해 확인해보면 a의 값은 거짓을 나타내는 자료형 None으로 나온다.
5. 입력값이 몇 개가 될지 모를 때
앞에서 알아본 함수의 형태와 같이 입력값의 갯수가 무조건 정해져있는 것은 아니다. 아래와 같은 방법을 통해 이런 부분을 해결할 수 있다. 아래의 소스코드는 예를 들어 sum_many(1, 2, 3)이면 6을 돌려주는 함수다.
>>> def sum_many(*args): <---- *입력 인수로 변형
... sum = 0
... for i in args:
... sum = sum + i <---- *args에서 입력받은 모든 값을 더한다.
... return sum
...
>>> result = sum_many(1, 2, 3)
>>> print(result)
6
>>> result = sum_many(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
>>> print(result)
55
앞서 사용하던 함수 형태에서 괄호 안의 입력 인수 부분을 '*입력 변수'로 바꿔주면 된다. 이렇게 사용하면 sum_many라는 함수의 입력값이 몇개든 상관없다. 위의 소스코드와 같이 *args처럼 입력 변수를 사용하면 입력값들을 전부 모아서 튜플로 만들어 준다. 예를들어 sum(many(1, 2, 3)이라고 함수를 쓰면 args는 (1, 2, 3)이 된다. 예시로 사용한 *args는 입력 인수를 뜻하는 영어단어인 arguments의 약자며 관례적으로 자주 사용하는 임의로 정한 변수 명이다. *pey, *python과 같이 아무 이름이나 사용해도 된다.
위 예시에서 사용한 def sum_many(*args)와 같이 함수의 인수로 *입력 변수만 사용할 수 있는 것은 아니다.
>>> def sum_many(choice, *args):
... if choice == "sum": <---- 입력 인수 choice에 'sum'을 입력 받을 때
... result = 0
... for i in args:
... result = result + i <---- args에 입력받은 모든 값을 더한다.
... elif choice == "mul": <---- 입력 인수 choice에 'mul'을 입력 받을 때
... result = 1
... for i in args: <---- args에 입력받은 모든 값을 곱한다.
... result = result * i
... return result <---- result 결과값을 출력한다.
...
>>> result = sum_many('sum', 1, 2, 3, 4, 5)
>>> print(result)
15
>>> result = sum_many('mul', 1, 2, 3, 4, 5)
>>> print(result)
120
위 소스코드를 보면 sum_many(choice, *args)에 위치한 choice 부분에 'sum'또는 'mul이라는 문자열을 입력하면 그에 따라 *args에 입력되는 모든 값을 더하거나 곱해서 결과값을 돌려준다.
6. 함수의 결과값은 언제나 하나다.
>>> def sum_and_mul(a, b):
... return a + b, a * b
...
>>> result = sum_and_mul(3, 4)
>>> print(result) <---- 튜플값 하나로 돌려준다.
(7, 12)
위 소스코드와 같이 결과값이 a+b와 a*b로 두 개가 있고 이를 받아들이는 변수는 result하나만 쓰였지만 sum_and_mul 함수의 결과값 a+b, a*b는 튜플값 하나인 (a+b, a*b)로 돌려주기 때문에 오류가 발생하지 않는다.
즉 위 소스코드의 결과값으로 (7, 12)라는 튜플값을 갖게 된다.
그리고 함수는 return문을 만나는 순간 결과값을 돌려준 후 함수에서 빠져나가게 된다. 그렇기 때문에 아래의 소스코드 두 가지는 완전히 같다는 뜻이 될 수 있으니 주의해서 사용하자.
# return 두 번 사용
>>> def sum_and_mul(a, b):
... return a + b
... return a * b
...
>>> result = sum_and_mul(2, 3)
>>> print(result)
5
# return 한 번 사용
>>> def sum_and_mul(a, b):
... return a + b
...
>>> result = sum_and_mul(2, 3)
>>> print(result)
5
첫 번째 소스코드를 보면 return문은 두 번 사용했지만 첫 번째에 위치한 return a + b가 실행됬기 때문에 두 번째에 위치한 return a * b는 실행되지 않는다.
그리고 어떤 특정 상황이 발생하면 함수를 빠져나가기 위해 return을 단독으로 써서 함수를 즉시 빠져나갈 수 있다.
>>> def say_nick(nick):
... if nick == "stupid": <---- nick의 입력값으로 'stuid'라는 값이 들어오면
... return <---- 문자열 출력 없이 함수를 즉시 빠져나간다.
... print("My nick name is {0}." .format(nick))
...
>>> say_nick('genius')
My nick name is genius.
>>> say_nick('stupid') <---- nick의 입력값으로 'stupid'가 입력되서 문자열 출력 없이 즉시 빠져나간다.
>>>
위 소스코드와 같이 'stupid'를 입력값으로 들어가면 즉시 return이 실행되어 함수를 빠져나간다. 이 방법은 실제 프로그래밍에서도 자주 사용된다고 하니 꼭 기억해두자.
7. 입력 인수에 초기값 미리 설정
앞서 살펴본 소스코드들의 인수에 아래와 같이 초기값을 미리 설정해 사용할 수 있다.
def say_myself(name, old, man = True): <---- man = True와 같이 입력 인수 미리 설정
print("My name is {0}." .format(name))
print("I am {0} years old." .format(old))
if man:
print("I am a man.")
else:
print("I am a woman.")
함수의 입력 인수에 들어갈 값이 변하는 것이 아닐 경우 위와 같이 함수의 초기값을 설정해 두면 유용하다.
# 초기값이 True인 경우
say_myself("Henry", 33) <---- man 변수에 입력값이 없으면 초기값인 True를 갖게 된다.
say_myself("Henry", 33, True)
# 초기값이 True인 경우의 출력값
My name is Henry.
I am 33 years old.
I am a man.
# 초기값이 False인 경우
say_myself("Hyeonggi", 33, False)
# 초기값이 False인 경우의 출력값
My name is Hyeonggi.
I am 33 years old.
I am a woman.
이렇게 변수의 입력 인수에 초기값에 따라 결과가 출력된다. 이런 방법으로 함수를 사용할 때 초기값을 설정한 인수의 위치를 주의해야 한다. 초기값을 적용하기 위한 입력 변수들은 항상 뒤쪽에 위치해야 한다.
8. 함수 안에서 선언된 변수의 효력 범위
먼저 아래와 같이 함수 밖에 1을 대입한 a라는 변수를 생성하고, 결과값을 돌려주지 않는 vartest 함수를 선언한다. 그리고 vartest 함수에 입력값 a를 주고, a를 출력하는 print(a)를 입력한 결과를 확인해보자.
a = 1 <---- 함수 밖의 변수 a
def vartest_a(a): <---- vartest 함수 선언
a = a + 1
vartest_a(a) <---- 함수의 입력값으로 a
print(a) <---- a의 값 출력
1
변수 a의 값인 1에 +1을 했으니 2가 출력될 것 같았지만 결과값은 1이 나온다. 그 이유는 함수 안에서 만들어진 변수는 함수 안에서만 사용되는 '함수만의 변수'이기 때문이다. 즉, def vartest(a)에 입력 인수를 뜻하는 변수 a는 함수 밖의 변수 a와 다르다는 뜻이다.
이런 함수 안에서 함수 밖의 변수를 변경하는 방법은 아래와 같이 두 가지가 있다.
# return 사용하기
a = 1
def vartest(a):
a = a + 1
return a
a = vartest(a) <---- vartest(a) 결과값을 함수 밖의 변수 a에 대입
print(a)
# global 명령어 사용하기
a = 1
def vartest():
global a <---- 함수 밖의 변수 a를 직접 사용한다는 뜻
a = a + 1
vartest()
print(a)
return을 이용하는 방법과 global 명령어를 이용하는 방법이 있다. return을 이용해 a = vartest(a)라고 대입하면 a가 vartest함수의 결과값으로 바뀐다. 하지만 여기서도 vartest 함수 안의 변수 a는 함수 밖의 변수 a와 다른 것이다. global a라는 문장은 함수 밖의 변수 a를 함수 안에서 직접 사용하겠다는 뜻이다. 단, 함수는 독립적으로 존재하는 것이 좋기 때문에 global 명령어는 사용하지 않는 것이 좋다. 외부 변수에 종속적인 함수는 그다지 좋은 함수가 아니라고 한다.
내용 출처: 책 '점프 투 파이썬'의 내용
'Programing > Python' 카테고리의 다른 글
[Python 입문] 12. 파이썬 파일 읽고, 쓰기 (0) | 2020.03.25 |
---|---|
[Python 입문] 11. 파이썬 사용자 입력과 출력 (0) | 2020.03.24 |
[Python 입문] 9. 파이썬 제어문 - for (0) | 2020.03.19 |
[Python 입문] 8. 파이썬 제어문 - while (0) | 2020.03.17 |
[Python 입문] 7. 파이썬 제어문 - if (0) | 2020.03.17 |