목차
1. positional arguments
2. keyword arguments
3. positional arguments + keyword arguments
4. default value
5. 함수 정의 시 default value parameter를 non-default value parameter 앞에 정의하면 안되는 이유에 대한 추측
6. 추가과제들
참고
parameter-매개변수 (함수 선언 시의 이름)
arguments-인자, 인수(함수 호출 시 이름)
복수의 parameter 를 사용하는 가장 기본적 함수 정의 형태는 아래와 같다.
함수 호출 시 parameter의 순서대로 선언하는 것이 원칙이다.
컴퓨터가 앞에서부터 순서대로 할당하기 때문이다. 순서가 중요하다.
예외적으로 함수 호출 시 순서를 지키지 않아도 되는 방법이 있다.
아래와 같이 keyword arguments를 사용하는 것이다.
이렇게 하면 컴퓨터는 해당 키워드에 맞게 알아서 해석한다.
위의 연장선으로 positional arguments와 keyword arguments를 같이 사용할 수 있다.
중요한 것은 potisional이 keword 앞에 나와야 한다!
def love_you(my_name, your_name):
print(f"{my_name} loves {your_name}" )
위의 함수를 positional arguments+keyword arguments방식을 사용해 가능한 모든 경우의 수로 호출을 해보자.
1)love_you("A", your_name="B" )
2)love_you(my_name="A", "B" )
3)love_you(your_name="B", "A" )
결과:
1)만 작동하고 2)와 3)은 에러가 발생한다.
'SyntaxError: positional argument follows keyword argument'
default value는 함수 호출 시 parameter를 적지 않아도 기본값을 부여한다.
기본 예시는 아래와 같다.
가장 중요한 건 함수 선언 시 default value parameter가 non-default value parameter의 앞에 오면 안된다.
아래처럼 non-default value parameter가 default value parameter의 뒤에 나올 경우 오류가 발생한다.
def love_you(my_name = "정우성", your_name):
print(f"{my_name} loves {your_name}")
Traceback (most recent call last):
File "python", line 1
SyntaxError: non-default argument follows default argument
아래 코드는 디폴트 인자가 뒤에 온 예시로 문제 없이 실행된다.
def func(a, b, c="3" , d="4"):
print(f"{a} {b} {c} {d}" )
func(1, 2)
이번엔 default value parameter가 non-default value parameter의 앞에 올 수 있다고 가정해보자.
def func(a='1', b='2', c, d):
print(f"{a} {b} {c} {d}" )
func(1, 2)
호출된 함수의 (1, 2) 어느 요소에 할당 할 것인지 컴퓨터가 해석할 수가 없다.
아래의 예시는 더욱 더 혼란스럽다.
def func(a='1', b='2', c, d, e='5'):
print(f"{a} {b} {c} {d} {e}" )
func(3, 4, 5)
3,4,5 는 어디에 할당되어야 하는가?
c,d,e인가? ->순서대로 할당되어야 하는 법칙에 위배된다.
a,b,c인가? ->d가 값을 가지지 못하게 된다.
어찌해야 할지를 모르겠다. 컴퓨터도 그럴 것이다.
결론
파이썬은 기본적으로 순서대로 parameter들을 match하게 프로그램 되어있다.
default value parameter가 앞에 나와버리면 컴퓨터가 해석할 수 없는 방법이 되고 많은 오류가 발생할 것이다.
default value parameter를 non-default value parameter 앞에 정의 하지 말아야만 하는 이유라 생각한다.
------------------------추가과제----------------------------------
위 코드 실행시 아래의 에러가 발생한다.
Traceback (most recent call last):
File "python", line 7, in <module>
TypeError: func_param_with_var_args() missing 1 required keyword-only argument: 'age'
어떤 에러인지 알고 이를 해결하기 위해 args를 알아보자. (args는 non-keyworded arguments)
args는 arguments의 약자다. 함수 인수를 여러개 받을 때, 몇개의 인수가 들어올지 모를 때 사용한다. 즉, 복수의 인수를 받을 수 있는 것이다.
이름이 꼭 args일 필요는 없다. *tomato여도 된다. 다만 애스터리스크를 사용시 복수의 인수를 받게 된다는 것만 알면 된다. 간단한 예시를 살펴보자.
def func(a, b, *tomato):
print(a)
print(b)
print(tomato)
func(1,2,3,4,5,6,7,8,9)
결과
1
2
(3, 4, 5, 6, 7, 8, 9)
이제 문제로 주어진 코드에서 왜 오류가 발생했는지 알 수 있다.
"wecode", "01012341234", "seoul", 20이 입력됐다.
먼저 name에 "wecode가 할당된다. 그 뒤 *args가 나머지 인수들을 모두 흡수하고, 불쌍한 age는 아무것도 할당받지 못하여 오류가 발생한다.
여하튼 *args는 모든 인수를 흡수하기 때문에 맨 뒤에 써야한다.
이제 코드를 제대로 고쳐보자. age만 앞으로 보내주면 된다.
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("wecode", "01012341234", "seoul", 20)
결과
name=wecode
args=('seoul', 20)
age=01012341234
def func(a,b,**tomato):
print(a)
print(b)
print(tomato)
func(1,2,name="hi")
결과
1
2
{'name': 'hi'}
함수 정의할 때 키워드 인수는 반드시 맨 뒤 자리에 위치해야 한다.
그 점 때문에 오류가 난 것이다.
문제의 코드 실행시 아래의 에러가 발생한다.
Traceback (most recent call last):
File "python", line 1
def func_param_with_kwargs(name, age, **kwargs, address=0):
^
SyntaxError: invalid syntax
그러므로 **kwargs를 맨 뒤자리로 옮겨 문제를 해결할 수 있다.
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)
결과
name=wecode
age=20
kwargs={'mobile': '01012341234'}
address=seoul
위의 코드 실행 시 아래의 오류가 발생한다.
Traceback (most recent call last):
File "python", line 1
def mixed_params(name="wecode", *args, age, **kwargs, address):
^
SyntaxError: invalid syntax
위 코드는 함수 인자로 positional, default, variable positional, variable keyword, keyword-only 가 총 출동한 예제다.
이 인자들의 순서는 아래와 같다.
위의 순서에 맞게 함수를 바꿔 정의해보자
def mixed_params(age, name="wecode", *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, "wecode", "01012341234", "male" ,mobile="01012341234", address="seoul")
결과는 아래처럼 잘 나온다.
name=wecode
args=('01012341234', 'male')
age=20
kwargs={'mobile': '01012341234'}
address=seoul
참고한 자료
https://getkt.com/blog/python-keyword-only-arguments/
-----------------the end-----------------------------------------
사족)
현재시각 16:28, 아침부터 추가과제와 씨름하다 이제 끝났다. (세션 1시간 30분, 점심시간 1시간 제외)
해결하고 나니까 속이 후련하다.
쉽게 배우면 쉽게 잊히고, 어렵게 익힌 것은 오래 간다는 말로 스스로를 격려한다.