[python] function parameter #3 (가변 키워드 인자)

hamingu·2021년 4월 16일
2

가변 키워드 인자

또는 키워드 가변 인자라고 하며 **kwargs로 사용한다. kwargs는 args와 마찬가지로 관례적인 표현이다.

가변인자와 마찬가지로 복수의 인수를 전달받으나 차이점은 가변 키워드 인자는 키워드로 이루어진 인수를 받는다.

ex) "name" = "programingu", "age" = 29
위 예처럼 키워드로 이루어진 인수를 딕셔너리에 받는다.

가변인자처럼 가변 키워드 인자도 사용 위치가 매우 중요하다.
아래 오류 예시 코드를 보고 문제가 무엇인지 가변 키워드 인자는 어느 위치에 사용해야 하는지 알아보자

가변 키워드 인자 오류 예제

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)

 #오류 메시지 : SyntaxError: invalid syntax

해당 함수는 선언 자체가 되지 않는다. 이유가 무엇일까
아마도 가변 키워드 인자 뒤에 default parameter가 선언되서인 것 같다.

def func_param_with_kwargs(name, age, address=0, **kwargs):
    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")

#출력값
name=정우성
age=20
kwargs={'mobile': '01012341234'}
address=seoul

오류 없이 정상적으로 값이 출력된다.
name, age 매개변수의 위치에 맞게 "정우성", "20"의 인수가 입력되고 키워드 형식의 인수인 mobile = "01012341234"는 키워드만을 값으로 받는 **kwargs에 dafault parameter인 address에 초기 값이 아닌 새로운 값 "seoul"이 입력되었다.

❓ 이 오류는 왜 발생할까??

함수 선언에서부터 오류가 발생하며, 에러 메시지 또한 syntax 오류인 바람에 정확한 원인을 에러 메시지에서 찾기는 어려웠다.

다만, 가변 키워드 인자의 특성과 인수가 매개변수에 입력되는 과정의 상관관계를 따져가며 생각해보면 아래의 이유가 아닐까 싶다.

  • 가변 키워드 인자는 복수의 키워드 인수를 값으로 받는다
  • 가변 키워드 인자 뒤에 address = 0 이라는 dafault parameter 가 선언되었다.
  • 함수를 호출할 때 default parameter인 address = 0 값이 자동으로 입력된다.
  • address = 0은 키워드 형태이므로 dafault parameter 보다 앞에 선언된 가변 키워드 인자가 address = 0 이라는 인수를 값으로 받아버린다.
  • 따라서 함수 선언단계에서 이미 오류가 예정된 함수가 되는 것이다.
  • 나의 머리로는 이 외의 이유는 생각나지 않는다😢

    가변 키워드 인자 오류 예제 #2 (feat. 위치인수)

    또 다른 예제를 살펴보자

    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)

    해당 함수를 선언하면 또 선언에서부터 syntax error가 발생한다.

    앞의 예제에서는 가변 키워드 인자 뒤에 무조건 키워드 형태의 값만 입력될 default parameter 값이 있어서라고 예상했지만 현재 코드에서는 그냥 값만 인수로 받을 수도 있는 address라는 매개변수가 선언되어있다.

    그럼에도 오류가 발생하는 이유는 무엇일까??

    ❓ 이 오류는 또 왜 발생할까??

    가변 키워드 인자 뒤에 일반적인 매개변수가 선언되었어도 나중에 이 변수를 호출할 때 키워드 인자를 값으로 받을 수도 있기 때문이 아닐까 싶다.
    (그렇다면 선언은 되고 호출할 때 에러가 나야하는거 아닌가..? 그냥 가변 키워드 인자 뒤에 매개변수는 선언되어선 안되는 절대불변의 법칙인건가..?)

    우야든동 추측되는 에러를 수정해보자

    def mixed_params(name="아이유", *args, age,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 값이 누락되었다는 오류가 발생했다.

    가변인자가 age, address 매개변수보다 앞에 선언되는 바람에 입력되는 인수를 모두 값으로 받아들여서 인 것 같다.

    def mixed_params(name="아이유", age,address,*args, **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)

    위와 같이 선언해보니 또 다시 선언에서부터 오류가 발생했다.
    오류메시지는 non-default argument follows default argument
    직역하면 기본인수가 아닌 인수가 기본인수를 따른다.

    함수 호출 시 선택적으로 입력되는 name="아이유"값이 기본인수 보다 먼저 선언되었기 때문이다.
    수정해보자

    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")
    
    #결과값
    name=정우성
    args=('01012341234', 'male')
    age=20
    kwargs={'mobile': '01012341234'}
    address=seoul

    address는 함수를 호출할 때 키워드 인자로 입력받는게 조건이기에 age와 같은 위치에 두지 않았다. (호출 시 오류발생됨)
    위와 같이 선언 후 호출하면 결과 값도 무사히 호출된다.

    profile
    프로그래밍구

    0개의 댓글