이펙티브 파이썬 Item 25. 위치로만 인자를 지정하게 하거나 키워드로만 인자를 지정하게 해서 함수 호출을 명확하게 만들라

    요약

    • 위치 기반 인자를 의도치 않게 키워드 인자로 사용하는 경우, 함수 호출부와 강하게 결합함.
      • 이 때, 위치 기반 인자의 이름 변화가 이 함수를 호출하는 쪽에도 의도치 않게 영향을 줄 수 있음. 
    • 위치 기반 인자, 키워드 기반 인자를 강제할 수 있음.
      • 함수 호출부의 / 앞에 있는 인자들은 위치 기반 인자로만 사용됨.
      • 함수 호출부의 * 뒤에 있는 인자들은 키워드 인자로만 사용됨.
      • 함수 호출부의 /와 * 사이에 있는 인자들은 위치 + 키워드 인자로 둘다 사용될 수 있음. 
    • 함수 호출부에서 키워드 기반 인자를 사용하면, 인자의 뜻을 이해하기 쉬워 가독성이 좋아짐. 
      • 함수 내에서 옵션으로 사용하는 변수는 키워드 기반 인자로 사용하는 것이 좋음. 
      • 예를 들면, 함수 호출 시 에러를 던지고 말지를 결정한다는 형식으로... Throw=True이면 예외를 위로 던진다! 

     


    Item 25. 위치로만 인자를 지정하게 하거나 키워드로만 인자를 지정하게 해서 함수 호출을 명확하게 만들라

    앞선 아이템에서 위치 기반으로 여러 인자(*args)를 받거나 키워드 기반으로 여러 인자(**kwargs)를 받는 방법들을 공부했다. 그런데 이 방법에는 한 가지 큰 단점이 있다. 

    def hello(a,b=10):
        print(a,b)
        
    hello(a=10,b=10)

    a는 위치 기반으로 받는 인자인데, 키워드 인자로도 사용할 수 있다. 위치 기반 인자를 의도치 않게 키워드 인자로 사용 했을 때의 문제점은 무엇이 있을까? 

    def hello(q,b=10):
        print(q,b)
    
    hello(a=10,b=10)

    위치 기반 인자로 사용하던 a라는 인자를 함수에서 q라는 이름으로 바꾸게 되면, 이전에는 성공하던 hello(a=10, b=10)에서 에러가 발생하게 된다. a를 키워드 인자로 사용했었는데, 그 키워드 인자의 이름이 a → q로 바뀌게 되어서 hello() 함수에서 더는 a라는 키워드 인자를 요구하지 않기 때문이다. 

    '키워드 인자'는 특정 함수와 함수 호출부가 강하게 결합하는 것을 의미하는데, '위치 기반 인자'로 사용할 것을 '키워드 기반 인자'로 사용하게 되어서 발생한 문제다. 예를 들어 위치 기반 인자를 사용할 것이라고 생각했다면, 함수를 사용하는 사용자가 인자 이름에 의존할 것이라고는 전혀 생각하지 않는다.

    우리가 일반적으로 선언하는 함수들에서 각 인자들은 키워드 인자, 위치 기반 인자로 둘다 사용할 수 있다. 그렇다면 함수를 호출하는 쪽에서 반드시 위치 기반 인자나 키워드 기반 인자로 쓸 수 있도록 강제할 수 있을까? 그럴 수 있다.


    위치 기반 인자, 키워드 기반 인자 강제하기

    def func(a, /, b, *, d=10):
        print(a,b,d)
    
    func(10,b=10, d=10)
    func(10, 10, d=10)
    • 함수 시그니처 부분에 /, *를 이용하면 위치 기반 인자, 키워드 기반 인자를 강제할 수 있게 된다.
    • / 앞에 선언되는 인자는 반드시 위치 기반 인자로만 사용된다. 그렇지 않을 경우 런타임 에러 발생함. (a의 경우)
    • * 뒤에 선언되는 인자는 반드시 키워드 인자로만 사용된다. 그렇지 않을 경우 런타임 에러 발생함. (d의 경우)
    • /와 * 사이에 있는 인자는 위치 기반 인자, 키워드 기반 인자로 둘다 사용할 수 있다.  (b의 경우)

    댓글

    Designed by JB FACTORY