728x90

함수를 정의하는 데에 있어서 "유의사항"위주로 정리한다.

 

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

 

4. More Control Flow Tools — Python 3.9.0 documentation

 

docs.python.org

 

728x90

+ Recent posts