본 포스팅은 책 「두근두근 파이썬」을 참고하여 공부한 내용의 정리본입니다.
이전 게시글
두근두근 파이썬 Chapter 3 변수와 연산자 (fin)
2021/01/12 - [Programming/#Python] - [Python] 두근두근 파이썬 Chapter 3 제어문 (fin) (실습 결과 포함)
0. 들어가며
이전 포스팅에서는 반복문에 속하는 for문의 심화 버전과 while문, 그리고 이들을 제어하는 키워드 break, continue에 대해 다루었다. 이번 포스팅에서는 함수의 역할과 종류를 이해하고, 호출되는 함수에 값을 전달하기 위한 매개변수, 그리고 지역변수와 전역변수 등에 대해 다뤄볼 것이다.
1. 함수의 역할
함수란 프로그램을 구성하는 코드 덩어리 혹은 블록(block)으로 볼 수 있다. 이러한 함수는 필요할 때마다 호출 (function call)하여 사용하는데, 이런 함수들 중 특히 파이썬에서 미리 만들어 제공하는 함수를 '내장함수 (built-in function)'이라고 한다. 또한, 이런 내장 함수 이외에도 사용자가 직접 필요한 함수를 '사용자 정의 함수 (user defined function)'으로 만들어 사용할 수 있다. 이때, 사용자 정의 함수는 'def'라는 키워드로 정의한다.
# return문이 없는 함수 정의 및 호출 >>> defprint_star(): # 정의 print('******************') >>> print_star() # 호출 ******************
위의 print_star()와 같은 함수는 어떤 일을 하도록 정의된 명령어들의 집합으로 외부에서 호출할 때마다 수행되는 것을 확인할 수 있다.
LAB 4-1: 함수 정의와 호출
# 문항 1 >>> def print_star(): print('***************') ''' 호출하지 않았으므로 아무것도 실행되지 않는다. ''' # 문항 2 >>> def print_star(): print('***************') >>> print_start() >>> print_start() >>> print_start() >>> print_start() >>> print_start() >>> print_start() *************** *************** *************** *************** *************** ***************
LAB 4-2: 함수 정의와 호출
# 문항 1 >>> def print_stars5(): print('******************') print('******************') print('******************') print('******************') print('******************') >>> print_stars5() >>> print_stars5() ****************** ****************** ****************** ****************** ****************** ****************** ****************** ****************** ****************** ******************
LAB 4-3: 함수 정의와 호출
# 문항 1 >>> def print_star(): print('*************************') >>> def print_plus(): print('+++++++++++++++++++++++++') >>> def print_hash(): print('#########################') # 문항 2 >>> print_hash() >>> print_star() >>> print_plus() >>> print_plus() >>> print_star() >>> print_hash() ######################### ************************* +++++++++++++++++++++++++ +++++++++++++++++++++++++ ************************* #########################
지금까지 구현한 함수의 장점은 다음과 같이 요약해볼 수 있다.
- 하나의 큰 프로그램을 여러 부분을 나눠 구현함으로써 구조적 프로그래밍이 가능하다.
- 다른 프로그램에서 함수를 재사용하는 것이 가능하다.
- 코드의 가독성이 증가한다.
- 프로그램 수정 시에도 일부 함수만 수정하면 되기에 유지 관리가 쉬워진다.
- 이미 개발된 함수를 사용하면 프로그램 개발의 시간과 비용을 절약할 수 있다.
2. 함수와 매개변수
매개변수(parameter)란 함수나 매소드의 헤더(header)부에 위치하며, 함수 호출 시 실제 값을 전달받는 "변수"를 말한다. 반면, 인자(argument)란 실제로 함수나 메소드가 호출될 때 전달되는 "값"을 말한다. 이를 다음 예제에서 살펴보자.
>>> def foo(m, n): # m, n은 매개변수 (parameter) code ... return [n1, n2,...] >>> foo(3, 4) # 3, 4는 인자 (argument)
위에서 다루었던 별표 출력 함수 print_star() 역시 매개변수와 인자를 활용하여 결과를 출력할 수 있다.
>>> def print_star(n): for _ in range(n): print('*********************') >>> print_star(4) ********************* ********************* ********************* *********************
LAB 4-4: 다양한 별표와 패턴 출력
# 문항 1 >>> def print_star(n): for _ in range(n): print('****************') >>> print_star(10) **************** **************** **************** **************** **************** **************** **************** **************** **************** **************** # 문항 2 >>> def print_hash(n): for _ in range(n): print('###############') >>> print_hash(10) ############### ############### ############### ############### ############### ############### ############### ############### ############### ############### # 문항 3 >>> print_hash(6) ############### ############### ############### ############### ############### ############### # 문항 4 >>> def print_hash(n): for _ in range(n): print(_, '###############') >>> print_hash(6) 0 ############### 1 ############### 2 ############### 3 ############### 4 ############### 5 ###############
이와 같은 원리로 함수의 인자 값을 활용해 그때그때 원하는 결과값을 호출할 수 있다. 이때, 함수 정의 시 요구되었던 모든 매개변수는 함수 호출 시에 입력되어야 한다. 만일, 일부를 입력하지 않는다면 TypeError가 발생한다.
>>> def print_sum(a, b): result = a + b print('{}과 {}의 합은 {}입니다.'.format(a, b, result)) >>> print_sum(10, 20) >>> print_sum(100, 200) 10과 20의 합은 30입니다. 100과 200의 합은 300입니다. >>> print_sum(100) TypeError: print_sum() missing 1 required positional argument: 'b'
LAB 4-5: 두 수 연산을 수행하는 함수
# 문항 1 >>> def print_sub(a, b): result = a - b print('{}와 {}의 차는 {}입니다.'.format(a, b, result)) 10와 20의 차는 -10입니다. # 문항 2 >>> def print_mult(a, b): result = a * b print('{}와 {}의 곱은 {}입니다.'.format(a, b, result)) 10와 20의 곱은 200입니다.
3. 매개변수를 활용한 2차 방정식의 근 구하기
이차방정식의 근은 아래와 같은 근의 공식에 의해 구할 수 있다. 이와 같은 식을 통해 도출되는 2개의 근은 매개변수를 포함한 함수를 정의하여 쉽게 구할 수 있다.
위의 근의 공식에 입각하여 서로 다른 두 이차방정식의 근을 구해주었다. 이때, 새로운 방정식의 근을 구하는 과정에 있어 중복되는 코드를 반복해서 작성해야 한다는 번거로움이 있다.
# (a*x^2)+(2*x)-8 >>> a = 1 >>> b = 2 >>> c = -8 # 근의 공식에 의한 이차방정식의 두 근 >>> r1 = (-b + (b ** 2 - 4 * a * c) ** 0.5) / (2 * a) >>> r2 = (-b - (b ** 2 - 4 * a * c) ** 0.5) / (2 * a) >>> print('r1=', r1, 'r2=', r2) r1= 2.0 r2= -4.0 # 2 * x^2 - 6 * x - 8 >>> a = 2 >>> b = -6 >>> c = -8 # 근의 공식에 의한 이차방정식의 두 근 >>> r1 = (-b + (b ** 2 - 4 * a * c) ** 0.5) / (2 * a) >>> r2 = (-b - (b ** 2 - 4 * a * c) ** 0.5) / (2 * a) >>> print('r1=', r1, 'r2=', r2) r1= 4.0 r2= -1.0
이를 해결하기 위해 이차방정식의 근을 구하는 기능을 함수로 구현할 수 있다. 이렇게 함수를 구현해두면 매번 같은 코드를 반복하여 작성할 필요 없이 훨씬 간결한 코드로 편리하게 값을 구할 수 있다.
>>> def print_root(a, b, c): r1 = (-b + (b ** 2 - 4 * a * c) ** 0.5) / 2 * a r2 = (-b - (b ** 2 - 4 * a * c) ** 0.5) / 2 * a print('해는 {} 또는 {} 이다.'.format(r1, r2)) >>> print_root(1, 2, -8) 해는 2.0 또는 -4.0 이다. >>> print_root(2, -6, -8) 해는 16.0 또는 -4.0 이다.
LAB 4-6: 함수의 사용
# 문항 1-(1) >>> print_root(1, 4, -21) 해는 3.0 또는 -7.0 이다. # 문항 1-(2) >>> print_root(1, -6, 8) 해는 4.0 또는 2.0 이다. # 문항 2 >>> def print_area(width, height): area = width * height * 1/2 print('밑변 {}, 높이 {}인 삼각형의 면적은: {}'.format(width, height, int(area))) >>> print_area(10, 20) 밑변 10, 높이 20인 삼각형의 면적은: 100
4. 반환문 return
일반적으로 다음 도식과 같이 함수는 인자와 같은 입력 값으로부터 함수 내부의 블랙 박스 (black box)를 거쳐 결과를 반환한다. 이때, 함수 내부의 코드 수행 결과를 반환하려면 return 키워드를 사용할 수 있다.
>>> def get_sum(a, b): result = a + b return result >>> n1 = get_sum(10, 20) >>> print('10과 20의 합 =', n1) 10과 20의 합 = 30 >>> n2 = get_sum(100, 200) >>> print('100과 200의 합 =', n2) 100과 200의 합 = 300
더불어, return 키워드 이후에 바로 수식을 위치시켜 수식의 결과 값을 반환하는 명령도 가능하다. 즉 아래의 함수는 위의 get_sum(a, b) 함수와 동일한 결과를 반환한다.
>>> def get_sum(a, b): return a + b
또한, 함수의 반환 값을 튜플로 전달받을 수도 있다. 다음은 동시 할당으로 get_root(a, b, c) 함수의 결과값을 result1, result2에 각각 할당하는 방법이다.
>>> def get_root(a, b, c): r1 = (-b + (b ** 2 - 4 * a * c) ** 0.5) / (2 * a) r2 = (-b - (b ** 2 - 4 * a * c) ** 0.5) / (2 * a) return r1, r2 >>> result1, result2 = get_root(1, 2, -8) >>> print('해는 {} 또는 {} 이다.'.format(result1, result2)) 해는 2.0 또는 -4.0 이다.
LAB 4-7: 원의 면적과 둘레를 반환하는 함수
이와 같이 함수로부터 두 개 이상의 값을 반환하는 반환문을 다중 반환문 (multiple return statement)라고 한다. 이러한 다중 반환문에서 쉼표로 구분되는 두 개의 값은 튜플 형으로 반환이 이루어진다.
# 문항 1 >>> def circle_area_circum(radius): area = 3.14 * radius * radius circum = 2 * 3.14 * radius return area, circum >>> area, circum = circle_area_circum(10) >>> print('반지름 10인 원의 면적은 {}, 원의 둘레는 {}'.format(area, circum)) 반지름 10인 원의 면적은 314.0, 원의 둘레는 62.800000000000004
LAB 4-8: 다수의 결과를 반환하는 함수 만들기
# 문항 1 >>> def multiplies(n, m): res = list() for i in range(1, m+1): res.append(n * i) return res >>> r1, r2, r3, r4 = multiplies(3, 4) >>> print(r1, r2, r3, r4) 3 6 9 12 >>> r1, r2, r3, r4, r5 = multiplies(2, 5) print(r1, r2, r3, r4, r5) 2 4 6 8 10
5. 전역 변수 (global variable)
전역변수란 함수 외부에서 선언되거나 전체 영역에서 사용 가능한 변수를 말한다. 아래 예시에서 변수 a와 b는 전역변수로, print_sum() 함수 내부와 함수 외부에서 모두 참조한다.
>>> def print_sum(): result = a + b print('print_sum() 내부:', a, '과', b, '의 합은', result, '입니다.') >>> a = 10 >>> b = 20 >>> print_sum() print_sum() 내부: 10 과 20 의 합은 30 입니다. >>> result = a + b >>> print('print_sum() 외부:', a, '과', b, '의 합은', result, '입니다.') print_sum() 외부: 10 과 20 의 합은 30 입니다.
이때, 함수는 함수 내에서 정의된 지역변수 (local variable)를 함수 외부에서 정의된 전역 변수보다 우선적으로 참조 (reference)한다.
>>> def print_sum(): a = 100 b = 200 # 지역 변수 result = a + b print('print_sum() 내부:', a, '과', b, '의 합은', result, '입니다.') # 전역 변수 >>> a = 10 >>> b = 20 >>> print_sum() print_sum() 내부: 100 과 200 의 합은 300 입니다. >>> result = a + b >>> print('print_sum() 외부:', a, '과', b, '의 합은', result, '입니다.') print_sum() 외부: 10 과 20 의 합은 30 입니다.
global 키워드를 사용한 전역변수의 참조 방법
다음과 같이 global 키워드를 사용하여 전역 변수를 지정해주면, 함수 내부는 물론, 함수 외부의 파이썬 스크립트에서도 전역 변수에 할당된 값을 참조한다.
>>> def print_sum(): global a, b a = 100 b = 200 result = a + b print('print_sum() 내부:', a, '과', b, '의 합은', result, '입니다.') >>> a = 10 >>> b = 20 >>> print_sum() print_sum() 외부: 100 과 200 의 합은 300 입니다. >>> result = a + b >>> print('print_sum() 외부:', a, '과', b, '의 합은', result, '입니다.') print_sum() 외부: 100 과 200 의 합은 300 입니다.
전역 상수 (global constant)
위와 같은 전역 변수는 코드의 길이가 길어질 경우 에러의 주요 원인이 되므로 사용을 지양하는 것이 좋다. 반면, 전역 변수와 비슷한 의미로 전역 상수 (global constant)가 있다. 전역 상수는 보통 대문자로 선언되고, global 키워드로써 선언할 수 있으며, 모듈 전체에서 참조할 수 있는 상수이다.
>>> GLOBAL_VALUE = 1024 ... >>> def foo(): global GLOBAL_VALUE a = GLOBAL_VALUE * 100
이와 같은 전역 상수로는 대표적으로 math 모듈의 원주율 pi와 오일러 상수 e가 있다. 이러한 전역 상수들은 예외적으로 소문자로 표기한다.
다음 게시글
두근두근 파이썬 Chapter 4 함수와 입출력 (2)
2021/01/14 - [Programming/#Python] - [Python] 두근두근 파이썬 Chapter 4 함수와 입출력 (2) (실습 결과 포함)
I'm a Senior Student in Data Science !
데이터 사이언스를 공부하고 있는 4학년 학부생의 TIL 블로그입니다. 게시글이 도움 되셨다면 구독과 좋아요 :)
'Programming > #Python' 카테고리의 다른 글
[Python] 함수와 입출력 (fin) (실습 결과 포함) (0) | 2021.01.17 |
---|---|
[Python] 함수와 입출력 (2) (실습 결과 포함) (0) | 2021.01.14 |
[Python] 제어문 (fin) (실습 결과 포함) (0) | 2021.01.12 |
[Python] 제어문 (2) (실습 결과 포함) (0) | 2021.01.11 |
[Python] 제어문 (1) (실습 결과 포함) (0) | 2021.01.10 |