파이썬(Python)_함수의 기초

Youngboy_Engineer·2021년 7월 11일
0

파이썬(Python)

목록 보기
6/8
post-thumbnail

정돈된 책상은 효율을 높임!


1. 함수의 개념과 목적

  • 함수란?
    ㄴ 프로그램에서 어떤 특정 기능을 수행할 목적으로 만들어진 재사용 구조의 코드 부분


  • 함수의 장점
    1) 큰 프로그램을 여러 부분으로 나눌 수 있기 때문에 구조적 프로그래밍이 가능
    2) 동일 함수를 여러 곳에서 필요할 때마다 호출할 수 있음
    3) 수정이 용이


  • 함수의 사용 방법
(이미지 출처 : SW Expert Academy)



  • 순수 함수(pure function): 결과값 반환 외에 외부에 영향을 주지 않는 함수
  • 함수형 프로그래밍 지원 언어에서는 순수 함수를 인자, 반환값으로 사용

2. 함수 호출 및 선언

  • 함수의 호출
    ex. print(인자) 함수
a, b = 2, 3
c = a + b

print("내장함수 str.format()과 print()를 이용한 c의 결과 출력: {0}".format(c))

[결과]
내장함수 str.format()print()를 이용한 c의 결과 출력: 5



  • 함수의 선언
def 함수명 (매개변수):
    명령문1
    명령문2
    return



  • 예시) calc_sum( ) 함수 : 두 개의 값을 전달 받아 합을 구하는 사용자 정의 함수
def calc_sum(x, y): # 매개변수에 인자값 전달
    return x + y # calc_sum() 함수를 호출한 위치에 반환 값이 전달됨
    
a, b = 2, 3

c = calc_sum(a, b) # 반환값 5가 변수 c에 저장
d = calc_sum(a, c) # 반환값 7이 변수 d에 저장

print("사용자 정의 함수 calc_sum() 호출을 이용한 c의 결과: {0}".format(c))
print("사용자 정의 함수 calc_sum() 호출을 이용한 d의 결과: {0}".format(d))

[결과]
사용자 정의 함수 calc_sum() 호출을 이용한 c의 결과: 5
사용자 정의 함수 calc_sum() 호출을 이용한 c의 결과: 7



✨함수 선언의 위치 문제
파이썬(Python)과 같은 인터프리터 언어의 경우 함수 선언 위치가 매우 중요함

3. 함수의 유형

  • 매개변수 : 함수에 입력 값을 전달해야 하는가를 결정하는 요인
  • 반환 값 : 함수가 수행 결과를 호출한 곳으로 돌려줄 필요가 있는가를 결정하는 요인


- 함수의 유형

1) 매개변수와 반환 값 모두 O 함수

def func_parameters_return(x, y, z):
    print("매개변수로 전달된 값은 {0}, {1}, {2} 입니다.".format(x, y, z))
    print("매개변수와 반환값이 있는 함수입니다.")
    return "Hello, Python!"
    
ret_val = func_parameters_return(1, 2, 3)
print("func_parameters_return() 함수가 반환한 값: {0}".format(ret_val))

[결과]
매개변수로 전달된 값은 1, 2, 3 입니다.
매개변수와 반환값이 있는 함수입니다.
func_parameters_return() 함수가 반환한 값: Hello, Python!



2) 매개변수는 X, 반환 값 O 함수

def func_noparameters_return():
    print("매개변수가 없는 함수입니다.")
    return "Hello, Python!"
    
ret_val = func_noparameters_return()
print("func_noparameters_return() 함수가 반환한 값: {0}".format(ret_Val))

[결과]
매개변수가 없는 함수입니다.
func_noparameters_return() 함수가 반환한 값: Hello, Python!



3) 매개변수 O, 반환 값 X 함수

def func_parameters_noreturn(x, y, z):
    print("매개변수로 전달된 값은 {0}, {1}, {2} 입니다.".format(x, y, z))
    print("반환값이 없는 함수입니다.")
    
func_parameters_noreturn(1, 2, 3)

[결과]
매개변수로 전달된 값은 1, 2, 3 입니다.
반환값이 없는 함수입니다.



4) 매개변수와 반환 값 모두 X 함수

def func_noparameters_noreturn():
    print("매개변수와 반환값이 없는 함수입니다.")
    
func_noparameters_noreturn()

[결과]
매개변수와 반환값이 없는 함수입니다.

4. 함수와 매개변수

  • 매개변수 : 함수 호출 시 입력 값을 전달 받기 위한 변수
    전달받은 인자의 값에 의해 타입이 결정됨
    선언된 매개변수의 갯수만큼 인자 전달 가능

  • 매개변수와 전달된 갯수의 불일치 문제
    - TypeError의 문제가 발생


  • 언팩 연산자(*)
    - 매개변수의 갯수를 가변적으로 사용할 수 있도록 언팩 연산자(*) 제공
    - 매개변수에 적용 시 인자를 튜플 형식으로 처리함
    - 가변형 매개변수를 가장 마지막 매개변수로 지정해야 부작용 없이 사용할 수 있음

    - 언팩 연산자를 사용하는 튜플 형식의 가변 매개변수

 1 def calc_sum(*params): # 매개변수에 인자 값들이 튜플 형식으로 전달
 2     total = 0
 3     for val in params:
 4         total += val
 5     return total
 6
 7 ret_val = calc_sum(1, 2)
 8 print("calc_sum(1, 2) 함수가 반환한 값: {0}".format(ret_val))
 9
10 ret_val = calc_sum(1, 2, 3)
11 print("calc_sum(1, 2, 3) 함수가 반환한 값: {0}".format(ret_val))
12
13 ret_val = calc_sum(1, 2, 3, 4)
14 print("calc_sum(1, 2, 3, 4) 함수가 반환한 값: {0}".format(ret_val))

[결과]
calc_sum(1, 2) 함수가 반환한 값: 3
calc_sum(1, 2, 3) 함수가 반환한 값: 6
calc_sum(1, 2, 3, 4) 함수가 반환한 값: 10



- 명시적 매개변수와 가변 매개변수의 혼합 사용 예시

 1 def calc_sum(precision, *params):
 2     if precision == 0:
 3         total = 0 # 정수 0으로 초기화
 4     elif 0 < precision < 1:
 5         total = 0.0 # 부동소수점 0.0으로 초기화
 6
 7     for val in params:
 8         total += val
 9     return total
10
11 ret_val = calc_sum(0, 1, 2) # precision에 0, params에 1, 2가 인자로 전달
12 print("calc_sum(0, 1, 2) 함수가 반환한 값: {0}".format(ret_val))
13
14 ret_val = calc_sum(0.1, 1, 2) 
15 print("calc_sum(0.1, 1, 2) 함수가 반환한 값: {0}".format(ret_val))

[결과]
calc_sum(0, 1, 2) 함수가 반환한 값: 3
calc_sum(0.1, 1, 2) 함수가 반환한 값: 3.0



- 언팩 연산자를 사용하는 튜플 형식의 반환값 예시

 1 def calc_sum(precision1, precision2, *params):
 2     if precision1 == 0:
 3         total1 = 0
 4     elif 0 < precision1 < 1:
 5         total1 = 0.0
 6
 7     if precision2 == 0:
 8         total2 = 0
 9     elif 0 < precision2 < 1:
10         total2 = 0.0
11
12     for val in params:
13         total1 += val
14         total2 += val
15
16     return total1, total2
17
18 ret_val = calc_sum(0, 0.1, 1, 2)
19 print("calc_sum(0, 0.1, 1, 2) 함수가 반환한 값: {0}, {1}".format(*ret_val) # 언팩 연산자를 통해 ret_val의 반환값을 분리
20 print("calc_sum(0, 0.1, 1, 2) 함수가 반환한 값: {0}, {1}".format(ret_val[0], ret_val[1]) # 튜플의 개별 원소를 인덱스로 접근해 처리

[결과]
calc_sum(0, 0.1, 1, 2) 함수가 반환한 값: 3, 3.0
calc_sum(0, 0.1, 1, 2) 함수가 반환한 값: 3, 3.0



- 키워드 언팩 연산자(**)

  • 매개변수의 갯수를 가변적으로 사용할 수 있도록 함
  • 키워드 인자들을 전달해 매개변수를 딕셔너리 형식으로 처리함
 1 def use_keyword_arg_unpacking(**params):
 2     for k in params.keys(): # 키 리스트를 구함
 3        print("{0}: {1}".format(k, params[k]))
 4
 5 print("use_keyword_arg_unpacking()의 호출")
 6 use_keyword_arg_unpacking(a=1, b=2, c=3)
 
 [결과]
 use_keyword_arg_unpacking()의 호출
 a: 1
 b: 2
 c: 3



- 기본 값을 갖는 매개변수

  • 매개변수에 전달할 인자 값이 생략되었다면? 사용할 기본 값을 지정!
  • 기본 값을 가지는 매개변수는 일반 매개변수 앞에 위치할 수 없다!
 1 def calc(x, y, operator="+"): # "+"를 기본값으로 지정
 2     if operator == "+":
 3         return x + y
 4     else:
 5         return x - y
 6
 7 ret_val = calc(10, 5, "+")
 8 print("calc(10, 5, "+")의 결과 값: {0}".format(ret_val))
 9 ret_val = calc(10, 5, "-")
10 print("calc(10, 5, "-")의 결과 값: {0}".format(ret_val))
 
 [결과]
 calc(10, 5, "+")의 결과 값: 15
 calc(10, 5, "-")의 결과 값: 5
 



- scope : 변수의 유효범위

1) 전역 스코프 : 어디서나 접근 가능한 전역 변수
2) 함수 스코프 : 함수 내에서만 접근 가능한 지역 변수

  • 변수에 접근하는 절차
    1) 함수 스코프 내에서 가장 먼저 변수를 찾음
    2) 함수 스코프 내에 변수가 없을 경우 → 전역 스코프에서 변수를 찾음
    ※ 지역변수와 전역변수의 이름이 같을 경우, 전역변수가 가려져 접근하지 못할 수 있음
    → 접근하고자 하는 전역변수 앞에 global을 기술함
def change_global_var():
    global x
    x += 1

x = 5
change_global_var()
print("전역변수 x의 값: {0}".format(x))

[결과]
전역변수 x의 값: 6

5. 고급 함수 사용법

  • 중첩 함수
    1) 중첩함수를 포함하는 함수 내에서만 호출이 가능
    2) 중첩함수를 포함하는 함수의 스코프에도 접근이 가능
    - 함수 내에서 직접 선언해 호출할 수도 있고, 함수의 매개변수로 함수 인자를 전달받아 함수 내에서 호출해서 사용 가능

  • 매개변수에 함수 전달하기
    1) 프로그램의 유연성을 높이기 위해 함수를 매개변수로 전달하는 방식을 선호!
    2) But, 매번 함수를 선언해 사용하는 것이 불편할 수 있음

def calc(operator_fn, x, y):
    return operator_fn(x, y)

def plus(op1, op2):
    return op1 + op2
    
def minus(op1, op2):
    return op1 - op2

ret_val = calc(plus, 10, 5)
print("calc(plus, 10, 5)의 결과 값: {0}".format(ret_val))

ret_val = calc(minus, 10, 5)
print("calc(minus, 10, 5)의 결과 값: {0}".format(ret_val))

[결과]
calc(plus, 10, 5)의 결과 값: 15
calc(minus, 10, 5)의 결과 값: 5
  • 람다식 or 람다 함수
    1) 변수에 저장해 재사용이 가능한 함수처럼 사용함
    2) 기존의 함수처럼 매개변수의 인자로 전달함
    3) 함수의 매개변수에 직접 인자로 전달함
Lambda 매개변수 : 반환값
def calc(operator_fn, x, y):
    return operator_fn(x, y)
    
ret_val = calc(lambda a, b: a + b, 10, 5)
print("calc(lambda a, b: a + b, 10, 5)의 결과 값: {0}".format(ret_val))

ret_val = calc(lambda a, b: a - b, 10, 5)
print("calc(lambda a, b: a - b, 10, 5)의 결과 값: {0}".format(ret_val))

[결과]
calc(lambda a, b: a + b, 10, 5)의 결과 값: 15
calc(lambda a, b: a - b, 10, 5)의 결과 값: 5
  • 클로저
    1) 중첩함수에서 중첩함수를 포함하는 함수의 scope에 접근 가능
    2) 중첩함수 자체를 반환값으로 사용한다면?
    • 정보 은닉 구현 가능
    • 전역변수의 남용 방지
    • 메서드가 하나밖에 없는 객체를 만드는 것보다 우아한 구현이 가능
def outer_func():
    id = 0
    
    def inner_func():
        nonlocal id # 변수 id가 중첩함수인 inner_func 함수의 지역변수가 아님
                    # 변수 id 접근 시 outer_func 함수 스코프에서 찾게 만듦
        id += 1
        return id
    return inner_func

make_id = outer_func()
print("make_id() 호출의 결과: {0}".format(make_id()))
print("make_id() 호출의 결과: {0}".format(make_id()))
print("make_id() 호출의 결과: {0}".format(make_id()))

[결과]
make_id() 호출의 결과: 1
make_id() 호출의 결과: 2
make_id() 호출의 결과: 3

(이미지 출처 : SW Expert Academy)

함수를 활용하여 원의 둘레와 면적 구하기

😂 고급함수 파트에 들어서면서 무슨 말인지 이해가 되지 않는다 ㅠ.ㅠ 내일 다시 한 번 천천히 살펴봐야지...

해당 포스팅은 아래의 사이트를 참고하여 작성하였습니다.
SW Expert Academy https://swexpertacademy.com/

profile
개발 공부를 막 시작한 주니어입니다.

0개의 댓글