함수란 특정한 기능을 반복적으로 실행할 수 있는 작업을 할 수 있는 코드 블록이다.
함수를 사용하면 반복적인 작업들을 하지 않아도 된다.
이러한 함수는 파이썬 어플리케이션 모듈화에도 영향을 미치며 재사용할 수 있다.
❗️ 파이썬에서는 필요에 따라서 로드 할 수 있도록 만들어진 파일을 모듈(module)이라고 부른다.
❗️ 코드의 재활용성을 높이고 유지 보수를 쉽게 할 수 있는 방법은 여러 가지가 있다.
❗️ 이 중 코드를 여러 개의 파일로 분리하는 방법이 있다. 여러 개의 파일로 분리하여 관리하면 아래와 같은 장점이 있다.
🍏 bulit-in-functions
라고 불리는 파이썬 설치와 함께 사용될 수 있는 내장된 함수들이 있다.
🍏 bulit-in-functions
와 별개로 새로 만들어지는 함수들은 user-defined-functions
라고 불린다.
파이썬에서 함수를 만드는 몇 가지 규칙을 정리해보고자 한다.
아래는 함수의 문법을 나타낸 것이다.
def 함수이름 (파라미터):
"함수 내 문서"
함수 내용
return [표현식]
이렇게 정의된 함수는 들여쓰기(tab 혹은 빈칸 4칸)를 통해 구분한다.
가장 처음에는 함수에 대한 문서가 들어올 수 있으며 이는 선택사항이다. (없어도 문제 없다는 뜻)
함수에 대한 문서는 여러 줄이라면 """함수 내 문서"""
로 표현하여 나타낼 수 있다.
만약 함수를 지정했는데 함수 내용이 없다면 IndentationError
가 발생하게 된다.
파라미터는 인자라고도 불리는 def 옆의 소괄호 안에 들어가는 값이다.
함수에서는 파라미터들을 선택적으로 받을 수 있다.
파이썬에서 파라미터들은 위치에 따라 영향을 받는다. 따라서 파라미터를 어떤 순서로 받는지 정한대로 순서를 지켜서 인수(argument)를 넘겨야 한다.
❗️ 참조 vs 값
파이썬에서는 인수들이 참조로 함수에 전달된다. 즉, 객체의 주소값을 전달한다는 것이다.
참조로 전달되지만 immutable한 객체들은 값으로 전달된다.
따라서 immutable한 객체인 int, str 등은 값으로 전달되며 mutable한 객체인 list, dict과 같은 객체들은 참조값으로 전달된다.
파이썬의 인수에는 세 가지 종류가 있다.
필수 인수는 위치에 따라 전달되는 인수들이다.
순서를 지켜야하며 함수에서 파라미터로 정의했기 때문에 필수로 넘겨야하는 인수인 것이다.
예를 들어 아래와 같은 함수가 있다고 한다고 하자
def resume_info(first_name, last_name):
print(f"My name is {first_name},{last_name}.")
이 함수를 이용하려면 인수 두 개를 넣어야한다.
인수를 넣지 않고 함수를 실행시키면 TypeError
가 발생한다.
❗️참고❗️
print(f"My name is {first_name},{last_name}.")
는 아래와 같이 더 구체적으로 표현할 수 있다.
아래의 방식이 조금 더 많이 쓰이는 것 같다.print("My name is {},{}.".format(first_name, last_name))
키워드 인수는 위치 인수(positional arguments)로 전달하지 않고 키워드를 통해 함수에 전달하는 인수이다.
resume_info(last_name='Lee', first_name='Yunsu')
위의 예시로 든 함수의 필수 인자의 위치와 다르지만 키워드를 통해 내가 원하는 위치에 원하는 값을 넣어주고 있다. 키워드를 명시하면 해당 함수를 실행할 수 있으면 필수 인수들을 전달하기만 하면 순서는 상관없게 된다.
만약 함수에서 받게 되는 파라미터 값들에 대한 기본 값들을 설정하게 된다면 인수를 넘기지 않는 경우 기본값들이 설정된다.
def personal_data(name, type_p = 'human'):
print(f"Hello {name}, you are {type_p}")
위와 같은 경우 type_p
인수를 넘기지 않으면 함수에서 기본값인 'human'을 type_p의 자리에 출력한다.
이 때 주의해야할 점은 ❗️기본값으로 설정된 파라미터들은 기본값이 없는 파라미터 뒤에 등장해야한다❗️는 것이다.
기본값이 없는 파라미터 앞에 기본값이 있는 파라미터가 오게 된다면 SyntaxError
가 발생한다.
파이썬에서 return
은 함수를 종료하고 호출자에게 표현을 전달하는 것이다.
즉, 함수에서 return
을 만나게 된다면 표현을 반환하고 함수가 종료된다.
def just_return(name):
return f"Hello {name}"
그렇다면 아래의 함수처럼 return
을 따로 명시하지 않으면 어떻게 될까?
def just_print(name):
print(f"Hello {name}")
이 경우 파이썬은 return None
과 동일한 리턴을 하게 되며 함수를 실행하게 되었을 때 None
을 돌려받는다.
즉, 위의 함수는 아래의 함수와 같은 결과값을 얻게 된다.
def just_print(name):
print(f"Hello {name}")
return None
❓ return
과 print
의 차이는 무엇인가?
Print는 영수증처럼 원하는 값을 화면 상에 '출력' 하는 기능만 한다.
반면 Return은 다른 함수가 사용할 수 있게끔 값을 '반환'하는 것으로 가공된 결과를 가져다 주는 것이다.
print는 nonetype이기 때문에 출력된 결과물들을 연산할 수 없지만 return된 값들은 type에 따라 연산을 할 수 있다.
좋은 예시가 있어서 가져와보았다.
아메리카노에 시럽을 한 번 넣어 먹는 것을 좋아하는 A가 있다.
A가 카페에 가서 아메리카노를 시킨다.
A는 결제를 하면서 아메리카노 한 잔이 출력된 영수증을 받는다.
A가 아메리카노를 수령하고 나면 시럽을 한 번 넣어서 원하는 커피를 받는다.
이를 함수에 비유하자면 아래와 같다.
아메리카노에 시럽을 한 번 넣어서 먹는 것 = 함수(Function)
아메리카노 = 입력값(또는 입력 변수 , 입력 파라미터)
주문 내역이 적힌 영수증 = 출력(Print) 또는 출력값
A가 아메리카노에 시럽을 한 번 넣어서 시럽 넣은 아메리카노 만들기 = 함수 내부가 입력값을 받아 동작하는 것
시럽을 한 번 넣은 아메리카노 = 함수의 리턴값(또는 반환값)
리턴된 값은 다른 함수가 사용할 수 있게 그 값을 직접 가져와줄 수 있다.
음료에 설탕을 넣는 함수에 영수증을 넣으면 아무것도 나오지 않지만 그 함수에 시럽을 넣은 아메리카노를 넣는다면 시럽과 설탕을 넣은 아메리카노를 얻을 수 있는 것이다.
이를 파이썬 코드로 명확하게 봐보자.
def f1(x):
a = 3
b = 5
y = a * x + b
return y # y 값을 반환한다
...
c = f1(10) # c = 35
print(c)
>>> 35
함수 f1의 경우 y의 값의 반환이 되기 때문에 c를 출력하면 함수 f1의 파라미터 x에 10을 넣은 값을 출력한다. 반면 y값을 반환하지 않고 출력하는 함수에 넣어보자.
def f2(x):
a = 3
b = 5
y = a * x + b
print(y) # y 값을 출력한다
...
d = f2(10) # d = ?
>>> 35
print(d)
>>> None
f2의 경우 y의 값을 출력만 하기 때문에 d를 출력하는 함수에 넣게 되면 출력을 할 것이 없다고 나오게 된다.
f2의 파라미터 x에 10을 넣은 값을 보여주긴하지만 이것을 다른 함수에 넣을 수 있도록 값을 반환하지 않기 때문이다.