Function parameters

minch·2021년 7월 7일
0

Python

목록 보기
4/13
post-thumbnail

Python Function parameters

Python에서 함수는 parameter를 받아서 return값으로 output을 한다.

예를 들어,

def profile(name, age):
	print(f"name: {name}, age: {age}")
profile("James", 21)

여기서 def profile()안에 name, age가 parameters,
아래 profile()안의 "James", 21이 arguments 이다.

arguments들을 받아서 그 parameter로 함수에 적용하는 것이다.

위처럼 순서대로 parameter를 적용하거나,
아니면 keyword arguments(kwargs)를 이용하여 parameter를 지정할 수 있다.
(이때는 순서를 상관하지 않아도 된다.)

그러나 둘을 섞어쓸때에는 반드시 positional arguments가 keyword arguments보다 먼저 사용되어야 한다.

ex)

def profile(name, age):
	print(f"name: {name}, age: {age}")
profile(name = "James", 21)

error 발생, 순서를 바꾸면?

def profile(name, age):
	print(f"name: {name}, age: {age}")
profile(21, name = "James")
Traceback (most recent call last):
  File "/Users/choemin/Desktop/Project/peplit 1.py", line 3, in <module>
    profile(21, name = "James")
TypeError: profile() got multiple values for argument 'name'

name이 두번 지정되었다는 error 발생,

def profile(name, age):
	print(f"name: {name}, age: {age}")
profile("James", age = 21)
name: James, age: 21

위와 같은 방법으로 사용하여야 한다.

또, parameter에 default value를 지정하여 해당하는 값을 받지 않아도 함수를 실행할 수 있다.

하지만 default value parameter를 non-default value parameter 앞에 정의하면 안된다.

이러한 순서는 python에서 왜 중요한 것일까?

위 그림을 보면 parameter의 순서를 한 눈에 알아볼 수 있다.

  • 먼저 보통의 positional arguments들을 받는 parameter가 제일 앞에오고,
  • 그 다음으로 default value를 갖지만 positional arguments를 받는 parameter,
  • 세번째로 variable length positional arguments(가변 인수,*args)의 parameter,
  • 다음으로는 keyword arguments를 받는 parameter들 중, non-default value 그리고 default value 순서로,
  • 마지막으로는 variable length keyword arguments(가변 키워드 인수,**kwargs)가 온다.

default value parameter

그렇다면 default value parameter가 non-default 뒤에 정의해야하는 이유는 무엇일까?

python에서는 함수를 정의하거나 호출할 때 인수가 정확하게 호출 될 수 있는지에 평가를 하고 결정한다.
그래서 매개변수들 중에서 먼저 positional arguments들을 순서대로 할당하고, keyword arguments를 나중에 할당하게 된다.

위에서 보았던 ex)에서 에러가 발생한 이유도,

def profile(name, age):
	print(f"name: {name}, age: {age}")
profile(name = "James", 21)

positional argument 21이 먼저 name에 할당되고 남은 keyword argument가 중복해서 할당되고, age의 값을 지정할 수 없기 때문에 생기는 것이다.

그럼 예제를 살펴보면,

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

여기서 love_you("아이유","이정재") 함수를 사용했다고 가정 했을때,
아이유라는 인수가 어떠한 parameter를 지정해는지 알 수 없기 때문에 이를 명시적으로 할당해 주어야 한다.
이 문제를 해결하기 위해서는 둘의 순서를 바꾸면 해결이 가능하다.

def love_you(your_name, my_name = "정우성"): 
   print(f"{my_name} loves {your_name}")
love_you("아이유", "이정재")
이정재 loves 아이유

가변 인수(variable length arguments)

가변 인수(aka. *args)는 arguments들 중 parmeter가 지정되지 않은 positional arguments들을 모두 불러온다.

예제 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)

name - "정우성" 순서대로 지정되고,
나머지 "01012341234", "seoul", 20이 모두 positional argument이기 때문에 다 불러와서 age 에 할당할 값이 사라지게 된다.

solution

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, "seoul", "01012341234")

*args를 맨 뒤로 보내고, age에 맞는 20값을 2번째에 둔다.

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)

age에 해당하는 인수를 keyword arguments로 만들어준다.

가변 키워드 인수 (variable length keyword arguments)

가변 키워드 인수(aka, **kwargs)는 지정되지 않은 모든 keyword arguments를 불러온다. 즉, (a = b)를 딕셔너리 형태 {a : b}로 함수에게 전달한다.

예제 2)

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

**kwargs는 항상 parameter의 마지막에 위치해야 한다!

solution

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

예제 3)

마지막으로는 *args와 **kwargs가 섞여있는 문제이다.

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

solution

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

positional arguments를 할당받는 age를 맨 앞으로 수정하고,
**kwargs를 맨 뒤로 수정하였다.

참조
(https://getkt.com/blog/python-keyword-only-arguments/)
(https://brunch.co.kr/@princox/180)

0개의 댓글