-
[Python] Arbitrary Argument Listsprograming/Language 2018. 10. 30. 21:51
안녕하세요, Einere입니다.
오늘은 python에서 Arbitrary Argument Lists를 알아보도록 하겠습니다.
Arbitrary Argument Lists
Arbitrary Argument Lists는 우리말로 하자면 "임의 인자 목록"정도로 되겠네요.
학교 수업에서는 가변인자리스트라고 배웠습니다.
하지만 학계가 원래 원명을 따르는 것이 좋으니 임의 인자목록이 좋겠네요.
임의 인자목록은 간단히 말해서 JS에서의 전개연선자(...)와 유사하다고 할 수 있습니다.
전통적인 언어인 C에서는 함수를 정의할 때, 인자의 타입과 순서를 명시해야 합니다.
그러나 파이썬에서는 기본인자값과 키워드인자와 임의인자목록을 사용할 수 있습니다.
Default Argument Values
전통적이고 기본적인 방식입니다.
인자를 정의할 때, 내부 변수로 활용할 이름으로 정의하며, 순서가 있습니다.
def ask_ok(prompt, retries=4, reminder='Please try again!'): while True: ok = input(prompt) if ok in ('y', 'ye', 'yes'): return True if ok in ('n', 'no', 'nop', 'nope'): return False retries = retries - 1 if retries < 0: raise ValueError('invalid user response') print(reminder)
파이썬 공식 홈페이지의 예시입니다.
위에서는 prompt인자가 바로 default argument value입니다.
위의 함수를 호출하는 방법으로는 다음과 같이 3가지 방법이 있습니다.
- giving only the mandatory argument: ask_ok('Do you really want to quit?')
- giving one of the optional arguments: ask_ok('OK to overwrite the file?', 2)
- or even giving all arguments: ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')
retries와 reminder는 밑에서 설명할 Keyword Arguments이므로
의무적 인자인 prompt만 넘기는 방법,
하나의 추가 인자를 넘기는 방법,
모든 인자를 넘기는 방법입니다.
Keyword Arguments
위의 예시에서 나온 retries, reminder와 같이 기본값이 설정된 인자입니다.
키워드 인자는 함수 호출시 값을 받지 못한다면 함수 정의부분에서 미리 정의한 값을 사용합니다.
단, 정의시 기본 인자값들 보다 오른쪽에 정의되어야 한다는 것입니다.
예를들어, "def foo(first=1, second)" 와 같은 식으로 정의할 수 없습니다.
여기서 미리 정의한 값은 보통 상수이지만, 변수로 설정할 수도 있습니다.
키워드 인자의 값을 변수로 정의하는 경우, 어느 시점의 변수값을 사용할까요?
정답은 함수가 정의되는 시점입니다.
i = 5 def f(arg=i): print(arg) i = 6 f() //print 5
위와 같은 경우, i에 5를 할당한 후 f라는 함수를 정의하고 i의 값을 6으로 바꾼 뒤, f()를 호출합니다.
그리고 f함수는 키워드 인자를 사용하고 있으며 해당 값은 i입니다.
f()가 정의되는 시점에서 i의 값은 5입니다.
따라서 f()를 호출하는 경우 출력되는 값은 5입니다.
Arbitrary Argument Lists
임의 인자 목록은 임의의 개수의 인자를 받아야 하는 경우에 유용한 방법입니다.
대표적인 경우로 range()함수가 있습니다.
인자가 하나일 경우 0부터 n-1까지 1단위로 리스트를 반환하며,
인자가 두개일 경우 n부터 m-1까지 1단위로 리스틀 반환하며,
인자가 세개일 경우 n부터 m-1까지 p단위로 리스트를 반환합니다.
def concat(*args, sep="/"): return sep.join(args) print(concat("earth", "mars", "venus")) // print 'earth/mars/venus' print(concat("earth", "mars", "venus", sep=".")) // print 'earth.mars.venus'
위의 예시에서 *args가 임의 인자 목록입니다.
인자명 앞에 *이 한개 붙습니다.
이렇게 *이 한개 붙은 인자는 함수 호출시 튜플로 감싸져서 넘겨집니다.
따라서 함수 내부에서 튜플 자체를 사용할 경우 "args"로 사용하며, 튜플 내부의 값을 사용할 경우에는 "*args"로 사용하면 됩니다.
def f(**arg): print(arg) # print(**arg) //error print(arg['a']) dic = {'a':1, 'b':2, 'c':3} f(**dic) // print {'a': 1, 'b': 2, 'c': 3} // print 1
*이 두개 붙는 인자도 있는데, 이것은 함수 호출시 딕셔너리로 감싸져서 넘겨집니다.
마찬가지로 딕셔너리 자체를 사용할 경우 "args"로, 내부 값을 사용할 경우에는 "args[key]"로 사용하면 됩니다.
임의 인자 목록도 키워드 인자와 같이, 기본 인자값보다 오른쪽에 정의되어야 합니다.
키워드 인자와 임의 인자 목록은 정의 순서가 상관없습니다.
Arbitrary Argument Lists를 사용하여 range함수 정의하기
임의 인자 목록을 사용하여 range()함수를 정의해보도록 하겠습니다.
import numpy as np def frange(a, *arg): if arg is (): return np.arange(0, a, 0.25) else: if len(arg) == 1: return np.arange(a, *arg, 0.25) else: return np.arange(a, *arg)
우선, step을 실수로 사용하기 위해 numpy를 import합니다.
그리고 임의 인자목록을 사용합니다.
인자가 1~3개일 수 있으므로, 기본 인자값인 a만 입력된 것을 판단하기 위해서 "arg is ()"를 조건문으로 사용합니다.
arg가 빈 튜플이 아닌경우라면 파라미터가 2~3개인 경우이므로, len()을 사용해 판별해줍니다.
참고
'programing > Language' 카테고리의 다른 글
[JavaScript] ArrayBuffer와 SharedArrayBuffer, Atomics (0) 2018.11.25 [Pycharm] '_xsrf' argument missing from POST 오류 해결법 (0) 2018.10.30 [JS] postfix를 이용해 실제로 계산하기 (0) 2018.10.09 [JS] js의 data structure (0) 2018.09.28 [npm] permission 관련 오류 해결법 (1) 2018.08.27 댓글