본문 바로가기

TIL

[TIL] #10. Function Parameters

Parameter

Parameter 정의할 때 발생하는 문제들

1. 함수를 정의할 때 default value parameter를 non-default value parameter 앞에 정의하면 안되는 이유

def multiply(a=2,b):
    print(a*b)

>> multiply(2)

메소드를 위와 같이 정의하면 SyntaxError: non-default argument follows default argument 가 발생한다. 그 이유는 만약에 메소드를 호출할 때 인자값을 1개만 전달하면 생략된 인자가 a 인지 b 인지 알 수가 없다. 따라서 b 에도 기본값을 지정해주거나 기본값을 지정해준 인자를 맨 뒤로 이동시켜 메소드를 정의하면 문제를 해결할 수 있다.

def multiply(a,b=2):
    print(a*b)

>> multiply(2)
4



2. 위치 인수(positional arguments)와 가변 인수(variable length 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", 20)

코드를 실행하면 다음과 같은 에러가 발생한다.

TypeError: func_param_with_var_args() missing 1 required keyword-only argument: 'age'

메소드에 정의된 인수의 위치를 보면 age가 가변인수 뒤에 위치해있다. 그런데 메소드를 호출할 때, argument를 지정하여 호출하지 않으면 가변인수때문에 두번째 인자부터 마지막 인자까지 모두 args인자로 인식되어 결과적으로 age인자에 아무 값도 들어오지 않게 된다. 이에 따라 'age'에 해당하는 argument가 없다고 에러가 나오는 것이다. 이를 막기 위해서 다음과 같이 메소드를 호출할 때 인자 이름을 명시적으로 표기해주면 문제를 해결할 수 있다.

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

또는 가변 인수를 맨 뒤에 정의하여 호출하는 방법도 가능하다.

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("정우성", 20, "01012341234", "seoul")



3. 가변 키워드 인수(variable length keyword arguments)의 위치

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")

코드를 실행하면 다음과 같은 에러가 발생한다.

File "main.py", line 1
    def func_param_with_kwargs(name, age, **kwargs, address=0):
                                                    ^
SyntaxError: invalid syntax

구문 오류가 발생하여 코드가 실행되지 않는다. 가변 키워드 인수는 일반 인수 앞에 올 수 없기 때문에 맨 뒤로 위치를 이동하여 메소드를 정의하면 문제를 해결할 수 있다.

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



4. 위치 인수와 키워드 가변 키워드 인수(variable length keyword arguments)의 위치

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")

코드를 실행하면 다음과 같은 에러가 발생한다.

Traceback (most recent call last):
  File "main.py", line 11, in <module>
    mixed_params(20, "정우성", "01012341234", "male" ,mobile="01012341234", address="seoul")
TypeError: mixed_params() got multiple values for argument 'address'

address 인자에 여러개의 값이 할당되었다는 에러가 발생했다. 먼저 인자 순서를 지키기 위해 가변인자들을 일반인자 뒤쪽으로 이동시키고 non-default value parameter를 맨 앞으로 이동시킨다. 그러면 다음과 같이 메소드가 정의된다.

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

mixed_params(20, "정우성", "01012341234", "male" ,mobile="01012341234", address="seoul")

하지만, 이렇게 해도 동일한 에러가 발생한다. 그 이유는 address라는 이름의 인자때문이다. 위에서 메소드를 호출할 때, mobile= , address= 로 인자를 할당하면 가변길이 키워드 인자로 인식되어 kwargs에 저장된다. 그런데 일반 인자명에도 address 가 있어서 address 라는 일반 인자로 값을 넘겨준 것인지, 키워드 인자로 값을 넘겨준 것인지 불분명하다. 이를 해결하기 위해서 메소드를 정의할 때 address 인자를 없애고 실행하면 정상적으로 동작하는 것을 확인할 수 있다.

def mixed_params(age, name="아이유", *args, **kwargs):
    print("name=",end=""), print(name)
    print("args=",end=""), print(args)
    print("age=",end=""), print(age)
    print("kwargs=",end=""), print(kwargs)

mixed_params(20, "정우성", "01012341234", "male" ,mobile="01012341234", address="seoul")
name=정우성
args=('01012341234', 'male')
age=20
kwargs={'mobile': '01012341234', 'address': 'seoul'}



‼️ 정리

  1. 기본값을 정의한 인자는 항상 기본값을 정의하지 않은 인자 뒤에 위치한다. 메소드 호출 시 인자를 생략한 경우 생략된 인자가 무엇인지 분명히 하기 위함.
  2. 가변 길이 인수는 되도록이면 위치 인수 뒤에 위치시키는게 좋다.
  3. 가변 키워드 인수는 일반 인수 또는 가변 길이 인수 앞에 올 수 없다.

'TIL' 카테고리의 다른 글

[TIL] #12. Absolute path & Relative path  (0) 2021.03.23
[TIL] #11. Module&Package  (0) 2021.03.23
[TIL] #9. Python 기초 문법  (0) 2021.03.19
[TIL] #8. HTML&CSS - 레이아웃  (0) 2021.03.17
[TIL] #7. Semantic Web, Semantic Tag  (0) 2021.03.16