본문 바로가기
BASIC

함수

by 자동매매 2023. 11. 19.

1. 빈 함수 만들기

내용이 없는 빈 함수를 만들 때는 코드 부분에 pass를 넣어줍니다.

def hello():
    pass

 

2. 함수 독스트링 사용하기

파이썬에서는 함수의 :(콜론) 바로 다음 줄에 """ """(큰따옴표 세 개)로 문자열을 입력하면 함수에 대한 설명을 넣을 수 있습니다. 이런 방식의 문자열을 독스트링(문서화 문자열, documentation strings, docstrings)이라고 합니다. 단, 독스트링의 윗줄에 다른 코드가 오면 안 됩니다.

def 함수이름(매개변수):
    """독스트링"""
    코드
 
def 함수이름(매개변수):
    """
    여러 줄로 된 
    독스트링
    """
    코드
 

독스트링은 ' '(작은따옴표), " "(큰따옴표), ''' '''(작은따옴표 세 개)로 만들어도 되지만, 파이썬 코딩 스타일 가이드(PEP 8)에서는 """ """(큰따옴표 세 개)를 권장합니다.

 

 

function_documentation_strings.py

def add(a, b):
    """이 함수는 a와 b를 더한 뒤 결과를 반환하는 함수입니다."""
    return a + b
 
x = add(10, 20)       # 함수를 호출해도 독스트링은 출력되지 않음
print(x)
 
print(add.__doc__)    # 함수의 __doc__로 독스트링 출력

실행 결과

30
이 함수는 a와 b를 더한 뒤 결과를 반환하는 함수입니다.

독스트링은 함수의 사용 방법만 기록할 뿐 add(10, 20)으로 함수를 호출해도 출력되지 않습니다. 독스트링을 출력하려면 print(add.__doc__)와 같이 함수의 __doc__을 출력하면 됩니다.

 

 

help(객체)

다음과 같이 help에 함수를 넣으면 함수의 이름, 매개변수, 독스트링을 도움말 형태로 출력해줍니다.

>>> help(add)
Help on function add in module __main__:
 
add(a, b)
    이 함수는 a와 b를 더한 뒤 결과를 반환하는 함수입니다.

 

 

3. 함수의 결과를 반환하기

앞에서 만든 add 함수는 두 수를 더해서 바로 출력했습니다. 그러면 함수에서 값을 꺼내 올 수는 없을까요?

다음과 같이 함수 안에서 return을 사용하면 값을 함수 바깥으로 반환합니다(return에 값을 지정하지 않으면 None을 반환).

def 함수이름(매개변수):
    return 반환값
 
 
 

return으로 함수 중간에서 빠져나오기

return은 값을 반환하는 기능뿐만 아니라 함수 중간에서 바로 빠져나오는 기능도 있습니다. 
이처럼 return은 함수 중간에서 빠져나올 때 자주 사용합니다. 보통은 if와 조합해서 특정 조건일 때 함수 중간에서 빠져나옵니다.
>>> def not_ten(a):
...     if a == 10:
...         return
...     print(a, '입니다.', sep='')
...
>>> not_ten(5)
5입니다.
>>> not_ten(10)
>>> 

 

4. 함수에서 위치 인수와 키워드 인수 사용하기

1) 위치 인수와 리스트 언패킹 사용하기

다음과 같이 함수에 인수를 순서대로 넣는 방식을 위치 인수(positional argument)라고 합니다. 즉, 인수의 위치가 정해져 있습니다.

>>> def print_numbers(a, b, c):
...     print(a)
...     print(b)
...     print(c)
...

print_numbers에 숫자 세 개를 넣으면 각 줄에 숫자가 출력됩니다.

>>> print_numbers(10, 20, 30)
10
20
30

list 언패킹 사용하기

이렇게 인수를 순서대로 넣을 때는 리스트나 튜플을 사용할 수도 있습니다. 다음과 같이 리스트 또는 튜플 앞에 *(애스터리스크)를 붙여서 함수에 넣어주면 됩니다.

  • 함수(*리스트)
  • 함수(*튜플)
>>> x = [10, 20, 30]
>>> print_numbers(*x)
10
20
30

 

>>> print_numbers(*[10, 20, 30])
10
20
30

단, 이때 함수의 매개변수 개수와 리스트의 요소 개수는 같아야 합니다. 

 

2) 가변 인수 함수 만들기

그럼 위치 인수와 리스트 언패킹은 어디에 사용할까요? 이 기능들은 인수의 개수가 정해지지 않은 가변 인수(variable argument)에 사용합니다. 즉, 같은 함수에 인수 한 개를 넣을 수도 있고, 열 개를 넣을 수도 있습니다. 또는, 인수를 넣지 않을 수도 있습니다.

다음과 같이 가변 인수 함수는 매개변수 앞에 *를 붙여서 만듭니다.

def 함수이름(*매개변수):
    코드

 

>>> def print_numbers(*args):
...     for arg in args:
...         print(arg)
...
 
>>> print_numbers(10)
10
>>> print_numbers(10, 20, 30, 40)
10
20
30
40
 

이렇게 함수에 인수 여러 개를 직접 넣어도 되고, 리스트(튜플) 언패킹을 사용해도 됩니다. 

>>> x = [10]
>>> print_numbers(*x)
10
>>> y = [10, 20, 30, 40]
>>> print_numbers(*y)
10
20
30
40

 

 

고정 인수와 가변 인수를 함께 사용하기

고정 인수와 가변 인수를 함께 사용할 때는 다음과 같이 고정 매개변수를 먼저 지정하고, 그 다음 매개변수에 *를 붙여주면 됩니다.

>>> def print_numbers(a, *args):
...     print(a)
...     print(args)
...
>>> print_numbers(1)
1
()
>>> print_numbers(1, 10, 20)
1
(10, 20)
>>> print_numbers(*[10, 20, 30])
10
(20, 30)
 
 

3. 키워드 인수 사용하기

인수의 순서와 용도를 모두 기억해야 해서 불편합니다. 그래서 파이썬에서는 인수의 순서와 용도를 매번 기억하지 않도록 키워드 인수(keyword argument)라는 기능을 제공합니다. 키워드 인수는 말 그대로 인수에 이름(키워드)을 붙이는 기능인데 키워드=값 형식으로 사용합니다.

  • 함수(키워드=값)
>>> def personal_info(name, age, address):
...     print('이름: ', name)
...     print('나이: ', age)
...     print('주소: ', address)
...

 

그럼 personal_info 함수를 키워드 인수 방식으로 호출해보겠습니다.

>>> personal_info(name='홍길동', age=30, address='서울시 용산구 이촌동')
이름:  홍길동
나이:  30
주소:  서울시 용산구 이촌동

키워드 인수를 사용하니 함수를 호출할 때 인수의 용도가 명확하게 보입니다. 특히 키워드 인수를 사용하면 인수의 순서를 맞추지 않아도 키워드에 해당하는 값이 들어갑니다.

>>> personal_info(age=30, address='서울시 용산구 이촌동', name='홍길동')
이름:  홍길동
나이:  30
주소:  서울시 용산구 이촌동

 

 

4. 키워드 인수와 딕셔너리 언패킹 사용하기

딕셔너리를 사용해서 키워드 인수로 값을 넣는 딕셔너리 언패킹을 사용해보겠습니다. 다음과 같이 딕셔너리 앞에 **(애스터리스크 두 개)를 붙여서 함수에 넣어줍니다.

  • 함수(**딕셔너리)
>>> x = {'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'}
>>> personal_info(**x)
이름:  홍길동
나이:  30
주소:  서울시 용산구 이촌동
>>> personal_info(**{'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'})
이름:  홍길동
나이:  30
주소:  서울시 용산구 이촌동

 

딕셔너리 언패킹을 사용할 때는 함수의 매개변수 이름과 딕셔너리의 키 이름이 같아야 합니다. 또한, 매개변수 개수와 딕셔너리 키의 개수도 같아야 합니다.

 
 **를 두 번 사용하는 이유

그런데 딕셔너리는 **처럼 *를 두 번 사용할까요? 왜냐하면 딕셔너리는 키-값 쌍 형태로 값이 저장되어 있기 때문입니다. 먼저 *를 한 번만 사용해서 함수를 호출해봅니다.

>>> x = {'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'}
>>> personal_info(*x)
이름:  name
나이:  age
주소:  address

 

personal_info *x를 넣으면 x의 키가 출력됩니다. 즉, 딕셔너리를 한 번 언패킹하면 키를 사용한다는 뜻이 됩니다. 따라서 **처럼 딕셔너리를 두 번 언패킹하여 값을 사용하도록 만들어야 합니다.

 
>>> x = {'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'}
>>> personal_info(**x)
이름:  홍길동
나이:  30
주소:  서울시 용산구 이촌동

 

5. 키워드 인수를 사용하는 가변 인수 함수 만들기

이번에는 키워드 인수를 사용하는 가변 인수 함수를 만들어보겠습니다. 다음과 같이 키워드 인수를 사용하는 가변 인수 함수는 매개변수 앞에 **를 붙여서 만듭니다.

def 함수이름(**매개변수):
    코드

 

이제 값 여러 개를 받아서 매개변수 이름과 값을 각 줄에 출력하는 함수를 만들어보겠습니다. 함수를 만들 때 괄호 안에 **kwargs와 같이 매개변수 앞에 **를 붙입니다. 함수 안에서는 for로 kwargs.items()를 반복하면서 print로 값을 출력합니다.

>>> def personal_info(**kwargs):
...     for kw, arg in kwargs.items():
...         print(kw, ': ', arg, sep='')
...

 

>>> personal_info(name='홍길동')
name: 홍길동
>>> personal_info(name='홍길동', age=30, address='서울시 용산구 이촌동')
name: 홍길동
age: 30
address: 서울시 용산구 이촌동

이렇게 인수를 직접 넣어도 되고, 딕셔너리 언패킹을 사용해도 됩니다. 다음과 같이 딕셔너리를 만들고 앞에 **를 붙여서 넣어봅니다.

>>> x = {'name': '홍길동'}
>>> personal_info(**x)
name: 홍길동
>>> y = {'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'}
>>> personal_info(**y)
name: 홍길동
age: 30
address: 서울시 용산구 이촌동

 

보통 **kwargs를 사용한 가변 인수 함수는 다음과 같이 함수 안에서 특정 키가 있는지 확인한 뒤 해당 기능을 만듭니다.

def personal_info(**kwargs):
    if 'name' in kwargs:    # in으로 딕셔너리 안에 특정 키가 있는지 확인
        print('이름: ', kwargs['name'])
    if 'age' in kwargs:
        print('나이: ', kwargs['age'])
    if 'address' in kwargs:
        print('주소: ', kwargs['address'])
 
 

고정 인수와 가변 인수(키워드 인수)를 함께 사용하기

고정 인수와 가변 인수(키워드 인수)를 함께 사용할 때는 다음과 같이 고정 매개변수를 먼저 지정하고, 그 다음 매개변수에 **를 붙여주면 됩니다.

>>> def personal_info(name, **kwargs):
...     print(name)
...     print(kwargs)
...
>>> personal_info('홍길동')
홍길동
{}
>>> personal_info('홍길동', age=30, address='서울시 용산구 이촌동')
홍길동
{'age': 30, 'address': '서울시 용산구 이촌동'}
>>> personal_info(**{'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'})
홍길동
{'age': 30, 'address': '서울시 용산구 이촌동'}

 

 

위치 인수와 키워드 인수를 함께 사용하기

함수에서 위치 인수를 받는 *args와 키워드 인수를 받는 **kwargs를 함께 사용할 수도 있습니다. 대표적인 함수가 print인데 print는 출력할 값을 위치 인수로 넣고 sep, end 등을 키워드 인수로 넣습니다. 다음과 같이 함수의 매개변수를 *args, **kwargs로 지정하면 위치 인수와 키워드 인수를 함께 사용합니다.

>>> def custom_print(*args, **kwargs):
...     print(*args, **kwargs)
...
>>> custom_print(1, 2, 3, sep=':', end='')
1:2:3

 

단, 이때 def custom_print(**kwargs, *args):처럼 **kwargs *args보다 앞쪽에 오면 안 됩니다. 매개변수 순서에서 **kwargs는 반드시 가장 뒤쪽에 와야 합니다.

 

특히 고정 매개변수와 *args, **kwargs를 함께 사용한다면 def custom_print(a, b, *args, **kwargs):처럼 매개변수는 고정 매개변수*args**kwargs 순으로 지정해야 합니다.

 

6. 매개변수에 초깃값 지정하기

지금까지 함수를 호출할 때 항상 인수를 넣어서 값을 전달했습니다. 그러면 인수를 생략할 수는 없을까요? 이때는 함수의 매개변수에 초깃값을 지정하면 됩니다. 초깃값은 다음과 같이 함수를 만들 때 매개변수=값 형식으로 지정합니다.

def 함수이름(매개변수=값):
    코드

 

매개변수의 초깃값은 주로 사용하는 값이 있으면서 가끔 다른 값을 사용해야 할 때 활용합니다. 대표적인 예가 print 함수인데, print 함수의 sep는 초깃값이 ' '(공백)으로 지정되어 있어서 대부분 그대로 사용하고, 가끔 sep에 다른 값을 넣어서 사용합니다.

 
>>> def personal_info(name, age, address='비공개'):
...     print('이름: ', name)
...     print('나이: ', age)
...     print('주소: ', address)
...

 

>>> personal_info('홍길동', 30)
이름:  홍길동
나이:  30
주소:  비공개

 

매개변수에 초깃값이 지정되어 있더라도 값을 넣으면 해당 값이 전달됩니다.

>>> personal_info('홍길동', 30, '서울시 용산구 이촌동')
이름:  홍길동
나이:  30
주소:  서울시 용산구 이촌동

 

초깃값이 지정된 매개변수의 위치

초깃값이 지정된 매개변수 다음에는 초깃값이 없는 매개변수가 올 수 없습니다. 

def personal_info(name, age, address='비공개'):
def personal_info(name, age=0, address='비공개'):
def personal_info(name='비공개', age=0, address='비공개'):

 

 

 

korean, english, mathematics, science = map(int, input().split())

def get_min_max_score(*args):
  return min(args), max(args)

def get_average(**kwargs):
  return sum(kwargs.values())/len(kwargs)


min_score, max_score = get_min_max_score(korean, english, mathematics, science)
average_score = get_average(korean=korean, english=english, mathematics=mathematics, science=science)
print('낮은 점수: {0:.2f}, 높은 점수: {1:.2f}, 평균 점수: {2:.2f}'.format(min_score, max_score, average_score))
 
min_score, max_score = get_min_max_score(english, science)
average_score = get_average(english=english, science=science)
print('낮은 점수: {0:.2f}, 높은 점수: {1:.2f}, 평균 점수: {2:.2f}'.format(min_score, max_score, average_score))

'BASIC' 카테고리의 다른 글

람다 표현식(lambda expression)  (1) 2023.11.22
재귀호출  (0) 2023.11.21
Exception  (0) 2023.11.19
덕타이핑 / 믹스인  (1) 2023.11.19
named tuple  (0) 2023.11.17

댓글