1월 27, 2022

Function Parameter 정리


1. 왜 default value parameter 를 non-default value parameter 앞에 선언하면 안될까??


함수의 파라미터에 default 값을 정의해줄 수 있습니다.

다만 주의해야 할 점은, default 값이 정의된 parameter 가 default 값이 정의되지 않은 parameter 보다 먼저 위치해 있으면 안된다는 점입니다. 만일 default value parameter를 non-default value parameter 앞에 선언하면, syntax error가 발생합니다

1
2
3
4
5
def love_you(my_name = "정우성", your_name): #default 파라미터를 your_name이라는 non-default 앞에 선언함
print(f"{my_name} loves {your_name}")

Traceback (most recent call last):
File "python", line 1 # 선언하는 line1에서 오류가 난것 확인 가능
SyntaxError: non-default argument follows default argument

음..근데 왜 오류가 나는걸까요??

Syntax Error 이기에 파이썬 문법상 금지해놓은 경우입니다.


일단 이 사진을 보면서 각 parameter의 위치를 확인해보시면, Non-Default keyword-only argument가 Keyword-only Arguments with Default 보다 앞에 옵니다.

(당황)...??


사진 우측에 있는 얘네를 이야기 한 것입니다.

Non-Default keyword-only argument 는 말 그대로 기본값이 없는 키워드 온리 매개변수이고,

Keyword-only Arguments with Default 도 말그대로 기본값이 있는 키워드 온리 매개변수 입니다.

근데 자세히 보면 그렇지도 않습니다. non-default가 먼저 나오긴 하지만, non-default와 default가 혼재돼서 나오는 것을 확인해 볼 수 있습니다.

그럼 왜 에러가 뜨는걸까요...? 다시 한번 말하지만 syntax에러입니다. 문법 자체가 이러한 표현이 불가능하게 막아둔 것입니다. 

이렇게 막아둔 이유가 있습니다. 앞서 함수를 love_you("호날두") 로 호출한다면 "호날두"는 어디로 들어가야 할 지 길을 잃게 됩니다.  my_name에 들어가자니 your_name이 비어버리게 되죠.

non-default argument가 앞에 나옴으로서 함수에 주어진 값의 위치가 모호해지게 됩니다. 이러한 혼란을 피하고자 syntax error를 통하여 default-value parameter가 non-default value parameter 앞에 오는 것을 막은 듯 보입니다.


2. 위치 인수와 가변 인수 


1
2
3
4
5
6
def func_param_with_var_args(name, *args, age):
    print("name=",end=""), print(name)
    print("args=",end=""), print(args)
    print("age=",end=""), print(age)

func_param_with_var_args("정우성", "01012341234", "seoul", 20)

 해당 스크립트를 실행하면, 


이러한 에러가 뜹니다. 에러를 자세히 보면 코드를 쉽게 고칠 수 있습니다. 'age'라는 keyword-only argument를 놓치고 있다 합니다.

age앞의 *args가 가변형이기에 "정우성"을 제외한 나머지 값들을 모두 빨아들이기 때문입니다.

이를 해결하기 위한 방법입니다.

1. 함수를 정의할 때 *args를 age 뒤로 보내주면 에러가 나오지 않습니다.

2. 함수에 인수를 전달할 때 


이렇게 Non-default keyword only argument인 age에 값을 지정함을 안내하기 위해서 인수에 age=20 이렇게 키워드를 기록해주면 인수가 제 자리를 찾아갑니다


3. 가변 키워드 인수


1
2
3
4
5
6
7
def func_param_with_kwargs(name, age, **kwargs, address=0):
    print("name=",end=""), print(name)
    print("age=",end=""), print(age)
    print("kwargs=",end=""), print(kwargs)
    print("address=",end=""), print(address)
 
func_param_with_kwargs("정우성", "20", mobile="01012341234", address="seoul")

 해당 스크립트를 실행하면, SyntaxError가 나옵니다.

앞서 보았던 사진을 기억하시나요?? 가변 키워드 인수는 가장 마지막에 위치합니다.

파이썬 문법은 **kwargs 이후로 어떠한 인수도 넘길 수 없게 설정돼 있습니다.

**kwargs를 address=0 뒤에 배치하면 에러 없이 잘 출력됩니다


순서대로 name의 값은 "정우성", age의 값은 20 이 들어갑니다. 

Keyword only arguments with default인 address의 값이 순서상 마지막 인수로 주어졌지만,  address라는 키워드와 함께 주어졌기에 address값으로 들어가는 것을 볼 수 있습니다.


4. 모든 argument들


1
2
3
4
5
6
7
8
def mixed_params(name="아이유", *args, age, **kwargs, address):
    print("name=",end=""), print(name)
    print("args=",end=""), print(args)
    print("age=",end=""), print(age)
    print("kwargs=",end=""), print(kwargs)
    print("address=",end=""), print(address)

mixed_params(20, "정우성", "01012341234", "male" ,mobile="01012341234", address="seoul")

마찬가지로 SyntaxError가 발생합니다. 

에러 없이 작동하도록 매개변수들의 위치를 바꾸어 보겠습니다. 

1
2
3
4
5
6
7
8
def mixed_params(age, name="아이유", *args, address, **kwargs, ):
    print("name=",end=""), print(name)
    print("args=",end=""), print(args)
    print("age=",end=""), print(age)
    print("kwargs=",end=""), print(kwargs)
    print("address=",end=""), print(address)

mixed_params(20, "정우성", "01012341234", "male" ,mobile="01012341234", address="seoul")


위치 인수인 age가 제일 앞으로 이동해야 하며, default argument인 name="아이유"는 그다음 ,non default 키워드 인수인 address는 가변 인수의 뒤에, 가변 키워드 인수의 앞에 위치해야 합니다. 

주어진 인수의 순서대로 20이 age에, "정우성"이 default argument인 name에, "01012341234"와 male이 variable length positinal argument에 들어갑니다. 

Non-default keyword only argument여서 값이 없던 address에 "seoul"이라는 값이 주어집니다.

가변 키워드 인수에 mobile="01012341234"의 키워드와 값이 주어져 잘 출력되는 것을 확인했습니다.



https://getkt.com/blog/python-keyword-only-arguments/ 해당 블로그를 참조하여 포스팅을 작성했습니다.