[파이썬기초] 05. 함수

1.함수 만들기

1.1 기본 용어 학습

  • 함수를 사용하는 것을 함수 호출(function call)라고 함
  • 함수를 호출할 때 괄호 내부에 여러 자료를 넣게 되는데 이를 매개변수라고 함
  • 함수를 호출해 최종적으로 나오는 결과를 리턴값(return value)이라고 부름
    • 무의식적으로 우리가 len()을 사용하면서 len()의 리턴값인 문자열(혹은 리스트)의 길이를 계속 받아와서 사용하고 있었음
  • 함수는 한마디로 '코드의 집합'이며, 함수를 생성하는 기본 형태는 다음과 같음
def <함수이름> (<매개변수, ...>):
	<문장>
    (return value)
  • 함수명은 자유로이 짓되, 기존에 파이썬에서 사용하는 함수명은 피해야 함
  • 매개변수는 아예 받지 않는다면 괄호만 써도 되며, 하나 이상의 변수를 받아올 수도 있음
  • return은 사용하지 않아도 무관함
  • 함수의 장점은 하나의 큰 프로그램을 여러부분으로 나눠 작성할 수 있으므로 구조적인 프로그래밍이 가능하고, 함수의 재사용에 용이함
  • 코드의 가독성이 증가하고, 프로그램의 유지보수 및 개발시간과 비용이 절약됨

1.2 매개 변수와 인자

  • 매개변수(Parameter): 함수나 메소드 헤더부에 정의된 변수로 함수가 호출될 때 실제 값을 전달받는 변수
  • 전달인자(Argument): 함수나 메소드가 호출될 때 전달되는 실제 값을 말하며, 간단하게 인자라고도 함
def foo(m, n): # 전달받을 값을 가지는 변수 m, n == 매개변수
	code
    ...
    return n1[, n2, ...]

foo(3, 4) # foo라는 함수에 넘겨줄 값 3, 4 == 인자

1.2.1 매개변수의 기본

def print_n_times(value, n):
	for i in range(n):
    	print(value)
        
print_n_times("안녕하세요", 5)
  • 출력결과
안녕하세요
안녕하세요
안녕하세요
안녕하세요
안녕하세요
  • 함수 괄호 내부에 value와 n이라는 식별자르 입력
    • 이렇게 입력하면 이는 매개변수가 되며, 함수를 호출할 때 값을 입력하여 함수쪽으로 전달할 수 있음

1.2.2 매개변수와 관련된 TypeError

  • 함수를 호출할 때 매개변수를 넣지 않거나 더 많이 넣으면 아래와 같은 에러메시지를 출력함

- Case 1. 매개변수 n 값이 입력되지 않은 경우

...
print_n_times('안녕하세요') 
  • 출력 결과
...
  print_n_times('안녕하세요')
TypeError: print_n_times() missing 1 required positional arqument: 'n'
  • 반대로 매개변수가 더 많이 입력되는 경우 아래와 같은 에러메시지를 출력함
    - Case 2. 매개변수가 더 많이 입력되는 경우
...
print_n_times('안녕하세요', 10, 20) 
  • 출력 결과
...
  print_n_times('안녕하세요', 10, 20)
TypeError: print_n_times() takes 2 positional arguments but 2 were given

1.2.2 기본 매개변수

  • 앞서 살펴본 range()함수는 매개변수가 세 개가 필요했으나, 생략해도 정상 동작함
    • 이는 특정 매개변수들이 기본값(default)을 갖고 있었기 때문
    • 이를 기본 매개변수 또는 디폴트 인자(default argument라고 부름
  • 기본 매개변수 뒤에는 일반 매개변수가 올 수 없다는 제약을 갖고 있음
  • 기본 매개변수를 설정할 때는 변수명 = 값의 형태로 작성하면 해당 변수에 값이 할당되지 않더라도 에러메시지가 뜨지 않음

1.2.3 가변 매개변수

  • 매개변수를 원하는 만큼 받을 수 있는 함수를 가변 매개변수라고 부름
  • 가변 매개변수 뒤에는 일반 매개변수가 올 수 없으며, 가변 매개변수는 하나만 사용할 수 있음
  • 다음과 같은 형태로 함수를 만듦
def <함수이름>(param1, param2, ..., <*가변매개변수>):
	<문장>

1.2.4 키워드 매개변수

1.2.4.1 기본 매개변수가 가변 매개변수보다 앞에 올 때

def print_n_times(n=2, *values):
	for i in range(n):
    	for value in values:
        	print(value)
        print()
        
print_n_times("안녕하세요", "즐거운", "파이썬 프로그래밍")
  • 위와 같이 기본 매개변수가 가변 매개변수보다 앞에 올 때는 기본 매개변수의 의미가 사라짐
  • 매개변수가 순서대로 입력
    • n에는 "안녕하세요"가 들어가고, values에는 ["즐거운", "파이썬 프로그래밍"]이 들어감
  • range()의 매개변수에는 숫자만 들어갈 수 있으므로 오류가 발생함
    • TypeError: 'str' object cannot be interpreted as an integer
  • 따라서 기본 매개변수는 가변 매개변수 앞에 써도 의미가 없음을 기억

1.2.4.2 가변 매개변수가 기본 매개변수보다 앞에 올 때

def print_n_times(*values, n=2):
	for i in range(n):
    	for value in values:
        	print(value)
        print()
        
print_n_times("안녕하세요", "즐거운", "파이썬 프로그래밍", 3)
  • 위의 코드는 두 가지로 예측이 가능
    • ["안녕하세요", "즐거운", "파이썬 프로그래밍"]을 세 번 출력
    • ["안녕하세요", "즐거운", "파이썬 프로그래밍", 3]을 두 번 출력
  • 실행해보면 두 번째 예상대로 실행됨
    • 가변 매개변수가 우선되기 때문
  • 이러한 상황을 대비해, 가변 매개변수와 기본 매개변수 둘 다 사용하기 위해 키워드 매개변수를 사용

1.2.4.3 키워드 매개변수

  • print()함수의 기본형을 살펴보면,
    print(value, ..., sep=' ', end='\n', file=sys,stdout, flush=False)
  • value를 여러개 입력할 수 있으므로 가변 매개변수를 맨 앞에 두고, 뒤에 기본 매개변수들이 들어간 형태
  • 이런 기본 매개변수가 지정된 함수를 사용할 때에는 매개변수 이름을 직접적으로 지정해서 값을 지정해 입력
  • 따라서 1.2.4.2에서 본 예제가 ["안녕하세요", "즐거운", "파이썬 프로그래밍"]을 세 번 출력하도록 하기 위해서는 매개변수 이름을 직접적으로 지정해서 값을 입력해야함
def print_n_times(*values, n=2):
	for i in range(n):
    	for value in values:
        	print(value)
        print()
        
print_n_times("안녕하세요", "즐거운", "파이썬 프로그래밍", n=3)

1.2.4.4 기본 매개변수 중에서 필요한 값만 입력

def test(a, b=10, c=100):
	print(a + b + c)
    
test(10, 20, 30) # Case 1. 기본 형태
test(a=10, b=100, c=200) # Case 2. 키워드 매개변수로 모든 매개변수를 지정한 형태
test(c=10, a=100, b=200) # Case 3. 키워드 매개변수로 모든 매개변수를 마구잡이로 지정한 형태
test(10, c=200) # Case 4. 키워드 매개변수로 일부 매개변수만 지정한 형태

- 출력 결과

60
310
310
220
  • 첫 번째 매개변수 a는 일반 매개변수이므로 해당위치에 반드시 입력해야하며, 일반 매개변수이지만 키워드 매개변수처럼 사용할 수도 있음
    • 따라서 Case 1, 2, 3번으로 작성했을 때 정상적으로 a값이 입력됨을 알 수 있음
  • Case 3을 살펴보면, 순서가 뒤섞인 것을 확인할 수 있는데, 키워드를 지정해서 입력하는 경우에는 이처럼 매개변수 순서를 원하는 대로 입력할 수 있음
  • Case 4는 b를 생략한 형태이지만 키워드 매개변수를 사용하면 필요한 매개변수에만 값을 전달할 수 있음
  • 즉,
    • 일반 매배견수는 필수로 입력해하고, 순서에 맞게 입력하면 됨
    • 기본 매개변수는 필요한 것만 키워드를 지정해서 입력하면 됨

1.3 리턴

  • 함수 내부에는 특정한 코드를 갖고 있으며, 주어진 일을 수행하고 결과를 반환함
  • 사용자는 보통 함수의 내부를 알 수 없음
    • 블랙박스(black box)라고 가정하고 사용함
  • return키워드를 사용하여 하나 이상의 값을 반환해줄 수 있음
  • return을 이용하여 값을 반환할 때는 return 키워드 다음에 수식이나 값을 입력하여 반환가능
  • 여러개의 값을 반환할 수도 있음

1.3.1 자료 없이 리턴

def return_test():
	print("A 위치입니다.")
    return
    print("B 위치입니다.")
    
return_test()

- 실행 결과
A 위치입니다.

  • return 키워드는 함수를 실행했던 위치로 돌아가라는 의미와 함수를 여기서 끝내라는 의미를 모두 갖고 있음
  • return을 만나는 순간 함수가 종료되므로 두 번째 print()문은 실행되지 않고 프로그램이 종료됨

1.3.2 자료와 함꼐 리턴

def return_test1():
	return 100

def return_test2():
	return 1, 2, 3

def return_test3():
	return
    
value_test1 = return_test1()
print(value_test1)

a, b, c = return_test2()
d = return_test2()
print(a, b, c, d)

value_test3 = return_test3()
print(value_test3)

- 출력 결과

100
1 2 3 (1, 2, 3)
None
  • return 키워드 뒤에 자료를 입력하면 해당 자료를 가지고 리턴함
  • 두 개 이상의 자료도 반환할 수 있으며, 이때 반환되는 형태는 튜플
  • 아무 값도 반환하지 않을 때는 None을 출력하며, VS Code에서는 경고문을 출력해줌
    • E1128: Assigning to function call which only returns None 이라고 경고

2. 재귀 함수

  • 함수 내부에서 자기자신을 호출하는 함수
  • 절차적 기법으로 해결하기 어려운 문제를 직관적이고 간단하게 해결 가능
  • 대표적인 예제로 팩토리얼(factorial)과 피보나치(fibonacci) 수가 있음
def factorial(n):
	if n == 0:
    	return 1
    else:
    	return n * factorial(n-1)

def fibonacci(n):
	if n in [1, 2]:
    	return 1
    else:
    	return fibonicci(n-1) + fibonacci(n-2)
  • 위와 같이 간단하게 코드를 작성할 수 있다는 장점이 있으나, 상황에 따라서 같은 것을 기하급수적으로 많이 반복한다는 문제 존재
  • 재귀함수는 무한히 자기자신을 호출하므로 탈출 조건을 반드시 명시해야함

3. 함수와 메소드

  • 함수와 메소드는 특정한 일을 하도록 정의된 동작을 수행한다는 점에서 동일
  • 뒤에서 자세히 다루겠지만, 차이점을 말해보자면,
    • 함수: 호출될 때 매개변수를 전달받아(생략가능) 특정한 동작을 수행하고 필요한 경우 그 결과를 반환하는 모든 프로그래밍 모듈
    • 메소드: 객체지향 프로그래밍에서 다루는 객체(object)에 부속되는 함수로, 메소드는 인스턴스(instance)라고 하는 각각 다른 값을 가진 객체들마다 호출 가능
  • 파이썬의 내장 함수의 예제는 아래와 같다
>>>> abs(-100) # 절대값 반환 함수
100
>>>> min(200, 100, 300 ,500) # 여러 원소 중 최솟값 반환
100
>>>> max(200, 100, 300, 500) # 여러 원소 중 최댓값 반환
500
>>>> str1 = "FOO"
>>>> len(str1) # str1의 인자의 성분 개수 반환
3
>>>> sorted('EBACD') # 성분을 오름차순으로 정렬
['A', 'B', 'C', 'D', 'E']
>>>> list_a = [100, 300, 200, 700]
>>>> sorted(list_a)
[100, 200, 300, 700]
>>>> sorted(list_a, reverse=True) # 성분을 내림차순으로 정렬
[700, 300, 200, 100]
>>>> id(str1) # 파이썬의 객체는 서로를 구별하는 식별값(C에서는 주소값)을 갖는데, 이 식별값을 정수형으로 출력
4549938992
>>>> n = 300
>>>> id(n)
4549735536
>>>> type(n) # 해당 변수의 자료형 반환
<class 'int'>
>>>> type('HELLO')
<class 'str'>
>>>> chr(65) # 유니코드로 반환
'A'
>>>> ord('A') # 문자를 유니코드 값으로 반환
65

아래는 5월 중 작성 예정

4. 함수 고급

4.1 튜플

4.2 람다

4.3 with 구문

좋은 웹페이지 즐겨찾기