ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TIL.41_2 function parameters(위치, 키워드인수)
    TIL 2020. 11. 19. 17:14
    728x90

    function 

    먼저 함수란 일정 작업을 수행하는 코드블럭으로 

    반복되는 코드를 줄여주기도 하며 코드의 가독성을 높혀준다.

    수학에서의 함수와 동일한 개념으로 input 이 있고, output이 있는 구조이다.

    def 함수명(parameter):
        문장1
        문장2
        ...
        문장N
        [return 리턴값]

     

    Parameter 란?

    매개변수 라고 부르며 정의한 함수에 이러한 매개변수를 이용하여 함수를 호출한다.

    아래 방법은 기본적인 함수 호출 방식으로 매개변수를 순서대로 입력하는

    위치인수 (positional arguments) 이며 기본적인 방법이다.

    def love (매개변수1, 매개변수2):
        print("{} LOVE {}".format(매개변수1, 매개변수2))
      # print(f"{매개변수1} LOVE {매개변수2}")
    
    love("정우성", "아잉유")
    #
    정우성 LOVE 아이유

     

    keyword Arguments (키워드 인수)

    파라미터의 순서를 지키지 않고도 값을 전달해 줄 수 있는데, 이를 keyword Arguments라 한다.

    키워드 인수는 함수를 호출할때 사용된다.

    순서가 바뀌어도 문제가없으며 어떠한 값을 넘겨주는지 명확하게 알 수 있어 가독성을 높혀준다

    (TIL. 26 참고하자 codermun-log.tistory.com/54)

    def love (매개변수1, 매개변수2):
        print("{} LOVE {}".format(매개변수1,매개변수2))
    
    love(매개변수2 = "아이유", 매개변수1 = "정우성") 
    #
    정우성 LOVE 아이유

     

    positional arguments (위치 인수) and keyword arguments (키워드 인수) 혼합 사용

    위치 인수와 키워드 인수는 아래와 같이 혼용하여 사용 할 수 있으나 위치 인수 부분은 순서를 지켜줘야 error가 나지 않는다.

    아래의 경우 키워드 인수가 위치 인수보다 앞에서 호출이 되어 위치 인수 순서를 지켜줘야하는데 순서가 틀렸기에 error가 발생한다

    def love (매개변수1, 매개변수2):
        print("{} LOVE {} POWER ".format(매개변수1,매개변수2))
    
    love("아이유", "정우성")
    # 아이유 LOVE 정우성 POWER 
    love(매개변수2 ="아이유", "정우성")
    # error

     

    Parameter Default value

    파라미터에는 초기값을 지정해 줄 수 있다, 여기서 초기값이 지정된 매개변수(파라미터)

    초기값이 지정되지 않은 인수보다 뒤에 위치해야 error가 나지 않는다.

    (초기값은 덮어씌울수 있다.)

    # love 와 love_2 함수 매개변수 순서 확인
    def love (매개변수1, 매개변수2 = "아이유"):
        print("{} LOVE {} POWER ".format(매개변수1,매개변수2))
    
    love("정우성")
    # 정우성 LOVE 아이유 POWER
    
    love("정우성", "유재석") # 초기값 덮어씌우기 가능
    # 정우성 LOVE 유재석 POWER
    
    def love_2 (매개변수1 = "정우성", 매개변수2):
        print("{} LOVE {} POWER ".format(매개변수1,매개변수2))
    
    Love_2("아이유") # SyntaxError: non-default argument follows default argument
    
    
    

     

    variable length arguments (가변 인수)를 이용한 가변 인수 함수 만들기

    관례적으로 *args라고 사용한다. (arguments) 사실 뭐라고 쓰든 자유다
    복수의 일반 인자를 사용자에게 입력받아서 사용할 때 쓰인다
    (정확히는, 정해지지 않은 수의 일반 인자)
    --> 여러개의 인자를 받은 경우, 함수 내부에서는 튜플로 받은 것처럼 인식한다.

     

    keyword Arguments (키워드 인수)를 이용한 가변 인수 함수 만들기

    위에서 언급한 바와 같이 키워드 인수는 함수 호출시 사용하는 기능으로 이용하였으나

    가변 인수 함수를 만들때 사용한 *args가 복수의 일반 인자를 받을때 사용했다면

    키워드 인수를 이용하여 복수의 키워드 인자를 받아와 사용할 수 있게 해준다.

    관례적으로 **kwargs라고 사용한다. (keyword arguments) 사실 뭐라고 쓰든 자유다
    *args와 다른 점이라면, **kwargs키워드로 이루어진 복수의 인자를 받는다
    (정확히는, 정해지지 않은 수의 키워드로 이루어진 인자)

     

    *args 와 **kwargs에 *(애스터리스크)를 사용하는 이유

    *args == *변수 --> 여러개의 args가 인자로 들어올때 함수 내부엣는 해당 변수를 "튜플"로 처리한다.

    따라서 args에 *(애스터리스크)를 사용하면 튜플 언패킹 효과를 이용하는 것과 같다.

    **kwargs == **변수 -->  키워드 = " "로 여러개의 키워드 인자가 들어올때 함수 내부에서는 "딕셔너리"로  처리한다.

    따라서 kwargs에 **를 사용하면 딕셔너리 언패킹 효과로 {키: 값} 중 "값"을 가져와 처리할 수 있다.

    상황에 따라 "키"를 이용한다면 kwargs에 *를 한번사용하면 된다

    (*딕셔너리 --> 딕셔너리를 한번 언패킹하면 "키" 만을 가져와 처리할 수 있다.)

     

    Keyword-Only Arguments(키워드 온리 인자)

     키워드 인자(keyword parameter)는 함수를 호출할 때 인자의 값 뿐만 아니라 그 이름까지 명시적으로 지정해서 전달하는 방법이다

    키워드 인자에는 두 종류가 있다.

    1. Non-Default Keyword-Only Arguments
    2. Default Keyword-Only Arguments

    1. Non-Default Keyword-Only Arguments == 함수 선언식의 매개변수에 Default 값이 없는 키워드 온리 인자를 의미한다.

    2. Default Keyword-Only Arguments == 함수 선언시 매개변수에 Default 값이 지정되어 있는 키워드 온리 인자를 의미한다.

    키워드 온리 인자는 아래에 나올 함수 정의시 순서에 중요한 요소 중의 하나이므로 새롭게 알게된 사실인 만큼

    잊어먹지 않도록 유의하자.

     

    Keyword-Only Arguments를 사용하는 이유는 아래와 같다.

    1. 가독성을 높혀준다.

    2. API 함수들이 함수의 모호함을 피하기 위해 키워드 온리 인자로만 중요한 인자들을 받을 수 있다.

    3. 키워드 온리 인자로만 인수를 받을 수 있도록 함수를 만들 수 있다.

    4. 함수가 엄청나게 많은 양의 인수들을 받는 때와 같은 selected case scenario에서 유용하게 사용된다고 한다.


    ## 함수 정의시 순서 ##

    최종적으로 아래 과제를 통해 함수 정의시 지켜야하는 순서에 대해 정리해보자

    일반 인수 >> 일반 Default 인수 >> 가변 인수 (*args) >> keyword-Only-Arguments >> 키워드 인수 (**kwargs) 순서를 지켜야한다

           age  >>     name="아이유" >>                *args  >>  address(Non-default-koa) >>  **kwargs 순이다

    def mixed_params(age, name="아이유", *args, address, **kwargs):
    
    mixed_params(20, "정우성", "01012341234", "male" ,mobile="01012341234", address="seoul")

    *args, **kwargs 문제 접근시 Tip

    아래와 같이 표시하면 한눈에 이해가 되어 문제 해결이 더욱 수월하였다.

    문제가 풀리지 않을때는 처음 기본으로 돌아가 다시 생각해보자

    def sum_of_numbers(*args):
        print(args)
    
    
    def what_is_my_full_name (**kwargs):
        print(kwargs)
    
    sum_of_numbers(1, 2, 3, 4, 5, 6, 7)
    (1, 2, 3, 4, 5, 6, 7)
    
    what_is_my_full_name(a=1, b=2, c="c", first_name="우성", last_name="정")
    {'a': 1, 'b': 2, 'c': 'c', 'first_name': '우성', 'last_name': '정'}

    Assignment

    해당 과제에서 가장 핵심은 

    함수 정의시

    매개변수의 특성과 함수 호출시 특정 인자의 특성에 따라

    정의하고, 호출하는데 중요한 순서를 확인하기 위함인것 같다.


    1. Parameter Default value 값을 지정할때 왜 지정된 파라미터가 뒤에 나와야하는 것일까

    먼저 초기값을 지정해준 (default value parameter) 매개변수 ad가 맨 뒤에 위치할 경우는

    값을 덮어씌울수도 주소를 입력하지 않아도 매개변수 ad 자리에는 "서울" 이 온다는 것을 컴퓨터가 알고 있다.

    def person_2 (name, age, ad="서울"):
    	print("이름: ", name)
    	print("나이: ", age)
    	print("이름: ", ad)
    
    person_2("홍길동", 40)
    #
    이름:  홍길동
    나이:  40
    이름:  서울
    
    

     

    하지만 default value parameter의 순서가 가운데에 온다면 어떻게 될까

    이때는 함수가 실행될때가 아닌, 정의된 함수가 처음 평가될때 발생하는 error이다.

    어떠한 값을 넣어도 호출할때는 애초에 잘못된 함수로 error가 발생한다.

    만약 이렇게 순서에 상관없이 함수가 정의된다면 person_2("홍길동", 30) 으로 호출할 경우를 생각해보자

    def person_2 (name, ad="서울" age):
    	print("이름: ", name)
    	print("나이: ", age)
    	print("이름: ", ad)
    
    person_2("홍길동", 30)
    #
    error

    ad = "서울"로 세팅이 된 초기값이 존재하는데, 이렇게 함수를 만들어버리면 30이 어디로 들어갈지 확실해 지지가 않는다.

    초기값 서울을 30으로 변경하라는 건지, 그렇게 되면 age가 비어버리게 된다.

    따라서 컴퓨터가 작업을 실행할때 애매모호한 상황이 되기 때문에 애초에 문법으로 지정해버린게 아닌가 싶다.


    2. 가변인수 에러 해결하기

    2.1 Solution_1

    가변 인수의 경우 인수가 몇개가 입력될지 알 수 없다

    가변 인수는 애초에 여러개의 인수를 입력받을때 사용하는 것으로 맨 마지막에 오는 것이 맞다고 생각한다.

    (실제로 초기값 설정 순서와 마찬가지로 아래 3개의 매개변수에서 가장 마지막에 위치해야 문법적으로 error가 나지 않는다.)

    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)

     

    error가 나지 않도록 아래와 같이 고쳐주자 

    (여기서 값을 *args를 사용시 함수 내에서 하나의 튜플을 이용해 처리한다는것을 기억하자)

    def func_param_with_var_args(name, age, *args):
        print("name=",end=""), print(name)
        print("args=",end=""), print(args)
        print("age=",end=""), print(age)
     
    func_param_with_var_args("정우성", "01012341234", "seoul", 20)
    #
    name=정우성
    args=('seoul', 20) # 값을 하나의 튜플로 반환시켜주는것을 기억하자
    age=01012341234

     

    error는 해결 하였으나 출력값을 연관성 있게 다시 고쳐주자.

    def func_param_with_var_args(name, age, *args):
        print("name=",end=""), print(name)
        print("age=",end=""), print(age)  # args와 순서 변경
        print("args=",end=""), print(args)
     
    func_param_with_var_args("정우성", 20, "01012341234", "seoul")
    #
    name=정우성
    age=20
    args=('01012341234', 'seoul')

    2.2 Solution_2

    Solution_1 에서는 매개변수와 아래 코드를 변경하여 해결하였지만

    해당 문제의 핵심은 다른곳에 있었다

    아래 동일한 문제를 함수를 호출하는 인자에 변화를 줘서 해결해보도록 하자.

    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 = 20 으로 변경하였더니 단 한군대만 수정하여 해결 할 수 있었다.

    이렇게 매개변수에는 특별한 특성이 없고 키워드 인자로 호출될 경우 keyword-Only-arguments (키워드 온리 인자) 중

    Non-Default keyword-Only-arguments 라고 부르며

    함수 정의시 *args (가변인자) >>> keyword-Only-arguments 순서로 키워드 인자가 뒤에 위치해야한다

    여기서는 함수 선억시 매개변수에 default값이 없는 Non-Default Keyword-Only-Arguments에 해당한다.

    # 매개변수의 함수 정의 순서 확인
    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", age = 20)
    #
    name=정우성
    args=('01012341234', 'seoul')
    age=20

    3. 키워드 인수를 사용한 가변 인수 에러 해결하기

    아래 함수를 호출할때 키워드 인수를 사용하였다

    그런데 mobile 이란 키워드가 없어 error가 난다

    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")
    #
    TypeError: func_param_with_kwargs() got an unexpected keyword argument 'mobile'

     

    이 문제에선 복수(몇개인지 알수없다 없거나 10개거나)의 키워드 인자를 받아 올 수 있도록 kwargs 앞에 **를 붙혀

    키워드 인수를 이용한 가변인수 함수로 만들어줘야 한다.

    여러개의 키워드 인자를 가져오기 때문에 아래 4개의 매개변수 중 가장 마지막에 위치해야 한다

    (이 문제에서는 Default keyword-Only-Arguments >>>> **kwargs (키워드 인수) 순서를 기억하자)

    (또한, 매개변수 **kwargs 사용시 함수 내에서 하나의 딕셔너리로 처리하는 것을 기억하자)

    def func_param_with_kwargs(name, age, address=0, **kwargs): # D-koa >>> **kwargs 순서
        print("name=",end=""), print(name)
        print("age=",end=""), print(age)
        print("address=",end=""), print(address)
        print("kwargs=",end=""), print(kwargs)
     
    func_param_with_kwargs("정우성", "20", mobile="01012341234", address="seoul")
    # 
    name=정우성
    age=20
    address=seoul
    kwargs={'mobile': '01012341234'} # 하나의 딕셔너리로 반환시켜주는것을 기억하자

    4. 위치인수와 키워드 인수를 이용한 가변 인수 함수 에러 해결하기

    아래는 매개변수의 순서로 인해 발생한 문법 error 이다.

    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: invalid syntax

    위에서 살펴보았든 해당 문제에서는 

    Keyword-Only-Arguments, *args (가변인수), **kwargs (키워드 인수) 순서에 대한 내용을 아는가? 에 대해 질문하고 있다.

    일반 인수 >> 일반 Default 인수 >> 가변 인수 (*args) >> keyword-Only-Arguments >> 키워드 인수 (**kwargs) 순서로 해결

    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 --> Non-Default keyword-Only-Arguments
    728x90
Designed by Tistory.