달구는 오늘도 코딩중!

[Python] 함수

austin lee 2023. 8. 1. 02:07

프로그래밍에 앞서, '함수'라는 말을 수학에서 먼저 떠올릴 텐데요,

수학에서 다루는 함수는 두 집합의 대응 관계를 나타냅니다.

프로그래밍에서 다루는 함수도 이와 비슷한데요, 마찬가지로 입력값(x)에 따라 출력값(y)이 변하게 됩니다.

다만, 프로그래밍에서는 '반복적으로 사용되는 부분'을 간단하게 작성하기 위해 사용하는 데 초첨을 더 둡니다.

(사실 함수를 사용하지 않아도 코드를 짤 수는 있지만, 함수를 사용하면 코딩이 엄청 편해집니다)

함수를 쓰지 않고 코딩하는 건 이 사진을 보고 '비둘기가 잘 난다!' 라며 감탄하는 것과 같습니다.

파이썬 함수의 구조는 다음과 같습니다.

def 함수명(매개변수):
    수행할 코드
    return 리턴값

매개변수는 함수에 입력으로 전달되는 값을 받는 변수입니다.

함수를 사용하는 것을 '함수를 호출한다'라고 표현하는데, 코드에서 함수를 호출하면 1) 매개변수를 받고 2) 함수의 기능이 작동하고 (수행할 코드의 내용) 3) 리턴값을 반환한다. 이처럼 함수는 들어온 입력값을 받은 후 어떤 처리를 하여 적절한 값을 리턴해 줍니다.

 

함수를 이용해 코딩을 하다 보면 '매개변수'와 '인수'라는 용어를 자주 혼동해 사용하기 때문에 잘 기억해 두어야 합니다. '매개변수'는 함수에 입력으로 전달된 값을 받는 변수인 반면, '인수'는 함수를 호출할 때 전달하는 입력값을 의미합니다.

def add(a, b):		<-- a,b는 매개변수
    return a+b

print(add(3, 4))	<-- 3,4는 인수
더보기

[출력 결과]

7

함수에 입력값을 넣으면 어떤 처리를 해서 적절한 값을 리턴해 주는 것이 일반적입니다. 하지만, 입력값이 항상 필요한 것은 아니며 리턴값 또한 항상 존재하는 것은 아닙니다.

 

함수를 호출할 때 매개변수 여러 개를 사용할 수 있는데요, 이때 매개변수의 값을 지정하거나 개수를 지정하지 않고도 사용할 수 있습니다.

매개변수를 지정하여 호출하기

def add(a=3, b=4):
    return a+b
    
n = 10
print(add(n))
더보기

[출력 결과]

14

함수를 선언할 때 위 코드처럼 매개변수의 초깃값을 설정할 수 있습니다. 이후 코드에서 함수를 호출할때 인자를 매개변수 개수보다 적게 선언하면 선언되지 않은 매개변수는 초깃값의 값을 가지게 됩니다. 위 코드에서 add(n)로 함수를 호출했는데, 그러면 매개변수는 각각 a=n, b=4의 값을 가지게 됩니다. 여기서 튜플이란, 리스트와 같은 배열형 자료구조입니다. 리스트와 거의 비슷하지만 리스트와 달리 ()으로 둘러싸며 요소값을 바꿀 수 없다는 차이점이 있습니다.

매개변수의 초깃값을 지정할 때 유의할 점은, 초깃값을 지정할 매개변수는 함수를 선언할 때 가장 뒤에 있어야 한다는 점입니다.

def add(a=4, b)
    return a+b
    
n = 7
print(add(n))

위 코드처럼 사용할 경우 함수 add를 호출할 때 b의 값이 선언되지 않아 에러가 발생합니다.

 

입력값의 개수를 모를 경우

def 함수명(*매개변수):
    수행할 코드

다음과 같이 선언하면 함수를 호출했을 때 인수들이 매개변수에 튜플로 담긴다. 여러 개의 입력을 처리할 때 함수의 매개변수로 *매개변수 하나만 사용할 수 있는 것은 아니며, 다음 예시처럼 매개변수 몇 개를 선언하고 마지막에 *매개변수 를 사용해 매개변수 개수보다 초과로 전달되는 인수들을 받을 수 있다.

def add_all(a, b, c, *nums):
    a += b+c
    for i in nums:
        a += i
    return a
    
p,q,r = 1,2,3
print(add_all(p,q,r,4,5,6,7,8))
더보기

[출력 결과]

36

단, *nums처럼 여러 개의 인수를 받는 매개변수는 가장 뒤에 선언되어야 합니다. 만약 *nums 뒤에 매개변수가 있다면 *nums에만 인수가 전달되고 그 뒤에 있는 매개변수에는 인수가 전달되지 못해 에러가 발생합니다.

 

*nums처럼 함수를 선언할 때 매개변수 앞에 * 1개를 붙이면 튜플로 여러 개의 인수를 받을 수 있는데요, **kwargs처럼 매개변수 앞에 * 2개를 붙이면 딕셔너리로 여러 개의 인수를 받을 수 있습니다. 이 경우에는 함수를 호출할 때 함수(key=value)와 같이 코드를 작성해야 합니다.

def add(**kwargs):
    print(kwargs)

add(a=1, b=2, c=3, d=4)
더보기

[출력 결과]

{'a': 1, 'b': 2, 'c': 3, 'd': 4}

매개변수의 초깃값을 지정하고 *와 **를 사용해 매개변수를 여러 개 받을 때, 선언하는 순서에 유의해야 합니다.

일반 매개변수 --> 초깃값이 있는 매개변수 --> *매개변수 --> **매개변수 순서로 선언해야 하며, 순서를 틀리게 선언할 경우 에러가 발생합니다.

 

지금까지 본 함수의 리턴값은 언제나 하나였는데요, 사실 파이썬에서 함수의 리턴값은 여러 개가 될 수 있습니다.

함수에서 값 여러 개를 return하기

def add_and_sub(a,b):
    return a+b, a-b
    
print(add_and_sub(17,5))
더보기

[출력 결과]

(22, 12)

위 코드와 같이 여러 개의 값을 return할 수 있습니다. 사실 return되는 값은 하나인데요, 출력 결과에서 짐작할 수 있겠지만 파이썬에서는 리턴값들을 하나의 튜플로 묶어서 return합니다.

 

지금까지 본 함수는 입력값을 받아서 특정 값을 return합니다. 그렇다면, 함수를 이용해 값을 return하는 대신에 변수의 값을 바꾸는 방법은 없을까요?

전역변수와 지역변수 : 함수 안에서 선언한 변수의 효력 범위

변수는 그 효력 범위에 따라서 크게 2가지로 나뉩니다. 지역변수는 함수 안에서 선언된 변수이며, 이를 선언한 함수 내부에서만 유효합니다. 반면 전역변수는 함수 밖에서 선언된 변수이며, 선언된 함수 내부에서도 유효합니다. 이 점을 이용하면 함수 안에서 함수 밖의 변수를 변경할 수 있는데요, 2가지 방법으로 구현할 수 있습니다.

1. return 사용

def increase_val(a):
    return a+4

n = 4
n = increase_val(4)
print(n)
더보기

[출력 결과]

8

함수의 리턴값을 함수 밖의 변수에 바로 대입하는 방식으로 함수 밖의 변수를 변경할 수 있습니다.

2. 전역변수 사용

def increase_val():
    global n
    n += 4

n = 4
increase_val()
print(n)
더보기

[출력 결과]

8

전역변수를 함수 내부에서 사용하려면 위 코드처럼 global 키워드를 이용해 선언해야 합니다. 이는 '함수 내부에서 전역변수를 사용하겠다' 라고 선언하는 과정이라고 생각하시면 됩니다. 이처럼 함수에서 전역변수에 직접 접근해서 값을 변경할 수도 있습니다.

 

lambda 예약어에 대해서는 여기서 다루지 않겠습니다. 개인적으로 가장 파이썬다운 문법 중 하나라고 생각하며 정말 유익한 툴이니깐 궁금하신 분들은 아래 링크 참고해 주시면 되겠습니다.

 

3.5 람다(lambda)

오늘은 람다 형식과 그것을 이용하는 여러 가지 함수들에 대해서 알아보겠습니다. 당장 완벽하게 소화하실 필요는 없을 것 같구요, 가벼운 마음으로 이런 것이 있다는 정도만 아셔도 되…

wikidocs.net

 

저는 다음에 더 유익한 내용과 함께 돌아오겠습니다.

 

<참고자료>

- 점프 투 파이썬 (박응용)

- 혼자 공부하는 파이썬 (윤인성)

'달구는 오늘도 코딩중!' 카테고리의 다른 글

[Pandas] DataFrame의 구조  (2) 2024.01.09
[Python] 집합 자료형  (0) 2023.07.13
[Python] 반복문  (0) 2023.07.02