함수를 정의하는 데에 있어서 "유의사항"위주로 정리한다.
def func(a, b=i):
# func 정의 후에 i를 다른 값으로 정의하더라도, 이전에 정의한 값을 사용한다. 이는 함수 정의할 때 default값이 계산된다는 것이다.
def func(a, L=[]):
L.append(a)
# default를 list, dictionary, instances of classes etc, "mutable"인 것을 받아서 함수 내부에서 mutable인 것을 수정하는 형태면, 그 func이 여러번 call될 때 마다 그 수정이 누적된다.
def func(a,b=2,c=3):
# 함수를 정의하는 데에 있어서 a가 positional argument인지 keyword argument인지 구분되는 것이 아니다. call할 때 구분한다.
# 함수를 call할 때 positional argument는 keyword argument보다 선행되어야 한다.
# func(a=1) # a는 keyword argument
# func(1,b=3) # positional argument 1개와 keyword argument 1개
# func(1, a=2) # a에 2개 값을 넣는 형태의 error, "got multiple values for keyword argument 'a'"가 뜬다.
def func(a,b=2,*args, **kwargs):
# 함수를 정의할 때 *args는 **kwargs보다 선행되어야 한다.
# arg는 func내부에서 tuple, kwargs는 dictionary type이다.
# func(1, c=3) # a=1, b=2, args=(), kwargs={'c':3}, 즉 default value가 args로 들어가는 것보다 우선순위가짐
# func(1,2,3,c=4) # a=1, b=2, args=(3,), kwargs={'c':4}
# func(1,2,3,4) # a=1, b=2, args=(3,4), kwargs={}
# func(1,2,3,4,**{'c':5, 'd':6}) # a=1, b=2, args=(3,4), kwargs={'c':5, 'd':6}
# func(1,2,3,4, **{'a':5}) # error, "got multiple values for keyword argument 'a'"
# kwargs에 들어간 keyword arguments의 순서는 call할 때 넣은 순서를 따른다.
def func(a,b=3):
# 함수를 call할 때 a,b모두 positional/keyword argument로 받을 수 있다.
# 함수를 정의할때부터 call할 때 positional/optional/keyword 어떤 형태로 받을지 강제할 수도 있다.
# def func(pos1, pos2, /, opt1, opt2, *, kwd1, kwd2): pos:positional-only, opt:optional, kwd:keyword-only
# 하지만 /과 *는 함수 정의할 때 optional이다. 하지만 적어준다면 call할 때 각 argument를 어떻게 받아야만 하는지 바로 이해할 수 있다.
def func(a,/):
# 즉 func은 반드시 positional argument로 call해야한다.
# func(a=3)는 "got come positional-only arguments passed as keyword arguments:'a'" ERROR
# def func(a)였다면 func(a=3), func(3) 모두 작동함
def func(*,a):
# func(3), "func takes 0 positional arguments but 1 was given" ERROR
# func(a=3)은 동작함
def func(a,/,b,*,c):
# func(1,2,c=3), func(1,b=2,c=3) 모두 동작함
# 즉 b는 positional/keyword 어떤 형태로든 받을 수 있음
def func(a,/,b=3,*,c):
# func(1,3,c=3), func(1,b=3,3), func(1,c=3) 모두 같은 동작함
# Positional-only인 a외에는 모두 default value 설정 가능
def func(a,b,*args, c):
# 입력을 여러개 받으면 args가 variadic variable인데 어디까지가 args이고 c인지를 알 수가 없는 형태
# 정의는 되지만 call하면 ERROR발생
def func(a,b,*args, c=4):
# 여러개 positional arguments를 받으면 a,b외 나머지는 args로, c는 4
# c를 4가 아닌 다른 값으로 사용하려면 반드시 keyword argument형태로 입력해줘야한다.
def func(a, **kwargs):
# **kwargs를 추가해줌으로써 함수를 정의할 때 여러개의 argument를 받을 수 있게 정의 가능
# func(**{'a':1, 'b':2})를 call하면 func내부에서 a=1이고 kwargs={'b':2}가 된다. 즉 kwargs(dictionary)를 unpack하여 함수 정의에 쓰였던 argument에 value를 assign하고, 함수 정의에 없던 argument는 kwargs가 갖고 있는다.
즉, def func(a, **kwargs): print(a, kwargs)에서 func(**{'a':1, 'b':2})를 call하면 1, {'b':2}를 print함
요약:
-함수를 call할 때 무조건 positional로 입력을 받아야할 때, /을 사용하여 강제를 하자.
(예를 들면 function을 call하는 입장에서 parameter name을 몰라야할 때)
-함수를 call할 때 keyword argument형태로 입력해야 사용자가 편리할 때 *을 사용하여 keyword argument를 강제하자.
(예를 들면 parameter의 순서보다는 parameter name이 의미가 있어서 입력을 할 때 함수를 좀 더 이해할 수 있을 때)
-함수를 정의할 당시에 가변적인 argument를 받아야하는데 parameter name이 유의미하지 않다면 *args를 사용
-함수를 정의할 당시에 가변적인 argument를 바다야하는데 parameter name이 유의미하다면 **kwargs를 사용, 이 때 kwargs로 받을 때 다른 argument name과 충돌하는 key-value를 받으면 multiple value assign ERROR발생
-함수를 정의를 어케하든 call할 때 **kwargs를 사용하여 argument에 value assign가능
참고자료:
https://docs.python.org/3/tutorial/controlflow.html#positional-only-parameters
'CS' 카테고리의 다른 글
[Algorithm]백준, 11726, 2×n 타일링 (0) | 2020.10.10 |
---|---|
(미완)[Algorithm]알고리즘의 유형, 알고리즘 문제의 유형 (0) | 2020.10.10 |
(진행중)[Elasticsearch]기본 사용법 모음 (0) | 2020.10.07 |
[Ubuntu]파일 찾기 자주 쓰는 명령어만 (0) | 2020.10.07 |
[python]Python 3.9로 upgrade하기 (0) | 2020.10.06 |