함수
포스트
취소

함수

함수(Funtion)란?

함수는 여러 번 사용할 수 있도록 코드를 묶어서 이름을 붙인 것이다.
반복되는 코드를 효율적으로 관리하고, 프로그램을 구조화하기 위해 사용한다.

관련 용어

  • 매개변수 (Parameter)
    • 함수에 입력으로 받는 변수
  • 인자 (Argument)
    • 함수를 호출할 때 넘기는 실제 값
  • 반환 값 (Return Value)
    • 함수를 호출했을 때 반환되는 값

함수 선언하기

def 키워드를 통해서 함수를 정의한다.

기본 사용법

def 함수명(매개변수1, 매개변수2, 매개변수3, ...):
    실행할 코드
    return 반환값

def 키워드를 통해 해당 코드가 함수를 선언하는 것임을 명시한다.
한 칸 띄고 함수의 이름을 명시한다.
바로 옆에는 소괄호를 치고 그 안에 필요한 매개변수 목록을 작성한다.
매개변수는 필요한 경우 작성하고, 필요하지 않다면 작성하지 않아도 된다.
하위에는 해당 함수에서 동작할 코드 목록을 작성해주고,
마지막으로 필요한 경우에 반환할 값을 작성한다.

예를 들어 a와 b라는 매개변수를 넘겼을 때
그 합을 출력하는 함수는 아래처럼 작성할 수 있다.

def add1(a, b):
    print(a + b)

이번에는 위 예제를 조금 바꿔서 a와 b라는 매개변수를 넘겼을 때
그 합을 반환하는 함수를 작성해보자.

def add2(a, b):
    return a + b

함수 사용법

그러면 선언한 함수는 어떻게 사용해야 하는 것일까?

반환 값이 없는 경우

반환 값이 없는 함수는 함수명과 인자를 작성하기만 하면 된다.
아까 예제로 만들었던 add1 함수를 호출해보자.

add(1, 2) # 출력 : 3

반환 값이 있는 경우

반환 값이 있는 경우에는 약간 다르다.
add1을 호출했듯이 add2를 add2(1, 2)로 호출하면
실제로 반응이 없다.

반환 값이 있는 경우에는 말 그대로 반환하는 무언가의 값이 있는 것이다.
이 때 반환되는 값을 사용하려면 값을 어딘가에 저장한 다음에 사용해야 한다.

return_value = add2(1, 2)
print(return_value) # 출력 : 3

반환 값이 없는 함수의 결과를 저장한다면?

반환 값이 없는 함수의 값을 변수에 저장하게 되면
반환 값이 없기 때문에 None이 저장된다.

다만 반환 값이 없다뿐이지 호출 자체는 했기 때문에
함수 내부의 코드는 진행된다.

none_return_value = add1(1, 2) # 이 과정에서 3을 출력한다.
print(none_return_value) # 출력 : None

다중 반환

다른 언어의 경우에는 하나의 함수는 하나의 값을 반환한다.
하지만 파이썬은 값을 여러 개 반환할 수 있다.
변수 선언 시 배웠던 패킹과 언패킹이 이 상황에서 사용된다.

아래의 예제를 살펴보면 이해할 수 있다.

def multiple_return():
  return 10, 20, 30

x, y, z = multiple_return()
print(x) # 출력 : 10
print(y) # 출력 : 20
print(z) # 출력 : 30

가변 인자 (Variable Arguments)

이전까지의 함수들은 매개변수의 개수가 정해져 있다.
그런데 만약 인자로 넘긴 값들을 더해서 출력하는 함수를 작성한다고 했을 때,
그 개수를 동적으로 넘기고 싶다면 어떻게 해야할까?

그럴 때 사용하는 것이 가변인자다.
매개변수를 명시하는 곳에 작성하는 것은 동일하다.
다만 매개변수 앞에 추가 기호를 붙여준다.

위치 가변 인자

위치 가변 인자는 가변 인자를 컬렉션처럼 사용하는 방법이다.
*매개변수로 명시하면 해당 매개변수는 컬렉션처럼 사용할 수 있다.

아래의 예제를 살펴보면 인자의 개수를 원하는 만큼 넘길 수 있는 것을 알 수 있다.

def sum(*args):
  sum = 0
  for i in args:
    sum += i
  print(sum)

sum(1, 2, 3) # 출력 : 6
sum(1, 2, 3, 4) # 출력 : 10
sum(1, 2, 3, 4, 5) # 출력 : 15

키워드 가변 인자

키워드 가변 인자는 가변 인자를 딕셔너리처럼 사용하는 방법이다.
**매개변수로 명시하면 해당 매개변수는 딕셔너리처럼 사용할 수 있다.

아래의 예제를 살펴보면 인자의 개수를 원하는 만큼 넘길 수 있는 것을 알 수 있다.

def dictionary_print(**args):
  for key in args:
    print(key, " : ", args[key])

dictionary_print(a=1, b=2, c=3)

키워드 가변 인자는 위치 가변 인자를 사용할 떄와 다르게
키=값처럼 사용한다.

혼합하는 경우

위 두 가지를 혼합해서 사용할 수도 있다.
첫번째로 가변 인자가 아닌 것이 인지된 다음에,
키=값 형태가 아닌 것들은 위치 가변 인자로,
키=값 형태인 것들은 키워드 가변 인자로 처리된다.

아래의 예제를 살펴보면 이해할 수 있다.

def mix(a, b, c, *args1, **args2):
  print(a)
  print(b)
  print(c)
  print(args1)
  print(args2)

mix(1, 2, 3, 4, 5, 6, key1=1, key2=2, key3=3)

다만 주의해야할 점은 키워드 가변 인자에서 사용하는 키의 이름이
다른 매개변수의 이름과 같으면 오류가 발생한다.
아래의 코드를 실행해보면 실제로 오류가 발생한다.

def mix(a, b, c, *args1, **args2):
  print(a)
  print(b)
  print(c)
  print(args1)
  print(args2)

mix(1, 2, 3, 4, 5, 6, a=1, b=2, c=3)

중첩 함수 (Nested Function)

파이썬에서는 함수 안에 함수를 선언하는 것이 가능하다.

def test(num):
    # 2를 곱하기
    def multiply2(num):
        return num * 2
    return_value = multiply2(num)
    print(return_value)

test(5) # 출력 : 10

이 때 중요한 것은 가장 바깥쪽에 선언된 함수만 사용할 수 있다는 것이다.
위 예제의 multiply2를 직접 호출하게 되면 오류가 발생하게 된다.

중첩 함수는 일반적인 함수 작성 시에는 드문 편이지만
데코레이터, 클로저, 팩토리 같은 고급 프로그래밍에서는 매우 중요하고 자주 사용된다.

타입 힌트 (Type Hint)

파이썬은 동적 언어라서 자료형을 따로 명시하지 않아도 되긴 한다.
하지만 그건 명시하지 않아도 된다는 뜻이지
자료형이라는 개념이 없는 것이 아니다.

함수를 작성하다 보면 이 함수가 어떤 역할인지 알기가 어려울 수 있다.
함수 안의 명령문이 10줄, 20줄 정도까지면 모를까
그 단위가 100 단위가 넘어간다면 함수를 빠르게 이해하기는 어렵다.

그래서 정수형을 넘겨야 하는데 문자형을 넘기거나,
문자형을 넘겨야 하는데 정수형을 넘기는 상황이 발생하기도 한다.
이러한 상황을 방지하지 하기 위해 사용하는 것이 타입 힌트다.

타입 힌트는 매개변수와 반환 값이 어떤 자료형인지 나타내기 위해 사용한다.
아래와 같이 사용하면 된다.

def sum(a: int, b: int) -> int:
    return a + b

return_value = sum(1, 2)
print(return_value)

매개변수 뒤에 :와 해당 매개변수의 타입을 지정하면 된다.
리턴 값의 타입은 매개변수를 선언하는 곳 뒤에 ->와 해당 리턴 값의 타입을 지정하면 된다.
주의해야 할 점은 def 함수명(매개변수):에서 (매개변수): 사이에 지정한다는 것이다.
:의 위치를 잘못 명시하거나 :의 개수가 달라지지 않도록 주의하자.

또한 타입 힌트는 typing 모듈이 있어야 한다.
파이썬 3.5 버전부터는 기본 모듈로 포함되있어서 바로 사용하면 되지만
3.5 미만에서는 타입 힌트를 사용하려면 모듈을 따로 추가해줘야 한다.

람다 함수 (Lambda Function)

람다 함수는 짧고 간단한 코드를 한 줄로 작성한 함수다.
lambda 키워드와 함께 명시한다.

lambda 매개변수_목록:실행할_코드처럼 사용하면 된다.
람다 함수는 기본적으로 함수명이 없는 익명 함수다.
그래서 변수에 저장해서 사용할 수 있다.
변수에 저장하게 되면 해당 변수명을 함수명처럼 사용할 수 있다.

# x + y가 반환 값이 된다.
add_lambda = lambda x, y: x + y

# add_lambda가 함수명이 된다.
return_value = add_lambda(2, 3)
print(return_value) # 출력 : 5

람다 함수는 복잡한 함수를 정의하지 않고 짧은 동작을 바로 쓸 때 유용하다.
별도의 함수 선언이 없어서 코드가 간결해지고 가독성이 올라갈 수는 있다.
다만 너무 남발하게 되면 오히려 가독성이 떨어질 수도 있으니 주의해서 사용하자.

출처

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.