Function Parameters

seyong·2021년 11월 20일
0
post-thumbnail

Python Function Parameters

Pyhton 에서 함수는 parameter를 받아서 return 값을 ouput으로 리턴한다.

그리고 함수를 호출할때는 parameter를 함수에 건내주어서 (pass)호출 한다.

함수의 parameter에는 여러 형태가 있는데 먼저, 가장 기본적인 형태는 순서대로 값이 parameter로 전해지는 경우이다. 이것을 Positional arguments 라고 한다.

Positional arguments

def my_profile(name,age):            
	print(f"제 이름은 {name}이고, 나이는{age} 입니다.")
 my_profile("박세용", 27)
# 제 이름은 박세용이고, 나이는 27 입니다. 

여기서 def my_profile(name,age) 괄호안에 name, ageparameter가 되고,
my_profile("박세용", 27) 괄호안에 "박세용", 27 arumenet가 된다.

Keyword Arguments

하지만 위의 경우 처럼 순서에 맞추어서 parameter 값을 전해주지 않을 수있다.

순서 대신 parameter 이름으로 맞추어서 값을 전해줄 수 있으며, 이를
keyword argments 라고 한다.

keyword argments 방식으로 parameter 값을 전해주면 실제 parameter 순서가 바뀌어도 괜찮다.

def my_profile(name,age):            
	print(f"제 이름은 {name}이고, 나이는{age} 입니다.")
my_profile(age = 27, name = "박세용")
# 제 이름은 박세용이고, 나이는 27 입니다. 

Keyword Arguments 를 사용하면

  • 순서가 바뀌어도 괜찮고, 가독성도 높아진다.

  • parameter 순서에 맞추어 값을 함수에 넘기는 경우, 실수로 값이 바뀌어도 알기 힘들다는 단점이있다.

  • 반면, 그에 비해 Keyword Arguments는 parameter 이름에 맞추어서 값을 함수에 넘기기에 실수로 값이 바뀔확률이 상대적으로 더 적다.

  • 또한 코드를 읽는 사람도 어떠한 값을 넘기는건지 명확하게 알 수 있기문에 가독성이 높아진다고도 할 수 있다.

Mixing positional arguments and keyword arguments

Mixing positional arguments and keyword arguments 는
순서를 맞추어서 parameter 값을 전해주는 positional arguments와
positional arguments를 혼용하여 사용하는것이다.

아래 예시를 보자.

def my_profile(name,age):            
	print(f"제 이름은 {name}이고, 나이는{age} 입니다.")
my_profile("박세용", age = 27)
# 제 이름은 박세용이고, 나이는 27 입니다. 

이렇게 사용이 가능하다는것인데 다만, 여기서 주의할 것은 keyword arguments 는 순서가 바뀌어도 상관 없지만 positional arguments 부분은 순서를 지켜줘야 한다는 것이다.

예를 들어, 아래 코드처럼 함수를 호출하면 error가 난다.

def my_profile(name,age):            
	print(f"제 이름은 {name}이고, 나이는{age} 입니다.")
my_profile(age = 27, "박세용")

> Traceback (most recent call last): File "python", line 1 SyntaxError: positional argument follows keyword argument

에러가 나는 이유는 keyword argument(age = 27)가 positional argument ("박세용")보다 더 앞으로 위치되어 함수가 호출되었기 때문이다.
Positional arguments는 순서를 지켜주어야 하는데 순서가 틀렸기 때문에 에러가 나는것이다.

Parameter Default Value

함수의 parameter에 default 값을 정의해 줄 수 도 있다. Default 값이 정의된 paramter는 함수가 호출될때 값이 넘겨지 않아도 괜찮다. 값이 넘겨지 않은 경우에는 default 값이 자동으로 넘겨지게 된다.

def my_profile(name,age=27):            
	print(f"제 이름은 {name}이고, 나이는{age} 입니다.")
my_profile("박세용")
# 제 이름은 박세용이고, 나이는 27 입니다. 

함수를 호출 할 때 2번쨰 parameter 값을 정의하지 않았으나 default 값이 정의 되어 있음으로 default 값이 자동으로 사용된다.
default 값 -> age = 27

다만, 조심해야 할점은 default 값이 정의된 parameter가 default 값이 정의 되지 않은 parameter보다 먼저 위치해 있으면 안된다는 점이다. 만일 default value parameter를 non-default value parameter 앞에 선언하면 아래 예시처럼 `syntax error`가 발생하게 된다.
def my_profile(name = "박세용", age):            
	print(f"제 이름은 {name}이고, 나이는{age} 입니다.")
my_profile(27") 

> Traceback (most recent call last): File "python", line 1
SyntaxError: non-default argument follows default argument

위와 같은 내용들을 공부하면서 문득 함수를 정의 할때 default value parameter를 non-default value parameter 앞에 정의 하면 안 되는 이유는 무엇일까에 대해서 궁금증이 생기게되었고, 그 이유에 대해서 파고들어보고싶어졌다.

함수를 정의 할때 default value parameter를 non-default value parameter 앞에 정의 하면 안 되는 이유는 무엇일까?

우선 위 그림을 천천히 살펴보면 parameter 의 전체적인 순서를 알아볼 수 있다.

위 그림을 보며 스스로 해석을 해보자면,

1. positional arguments들을 받는 parameter
2. default value를 갖지만 positional arguments를 받는 parameter
3. variable length positional arguments(가변 인수,*args)의 parameter 
4. keyword arguments를 받는 parameter들 중, non-default value 그리고 default value
5. variable length keyword arguments(가변 키워드 인수,**kwargs)

다음과 같은 순서를 가진다는것을 알 수 있다.
이순서들을 지키지않으면 문법적 오류가 발생하는데,
파라미터를 정의하는 순서를 지키지않고 생성하게되면 함수가 어떤 파라미터에 값을 받아야할지 혼동하게된다.

pyhton에서는 함수를 정의하거나 호출할 때 인수가 정확하게 호출 될 수 있는지에 평가를 하고 결정한다.

그래서 매개변수(argumenet) 중에서 positional arguments들을 순서대로 할당하고, keyword arguments를 나중에 할당하게 된다.

위에 예시를 들어 다시한번 살펴보면,

def my_profile(name = "박세용", age):            
	print(f"제 이름은 {name}이고, 나이는 {age} 입니다.")
my_profile(27) 

호출된 함수 my_profile("27") 가 함수의 첫번째 매개변수 name="박세용" 로 들어가야 정상적으로 호출이 되는데 이미 매개변수 name = "박세용" 에는 "박세용"이라는 인자값을 받고있기 때문에 문법적오류가 발생하는것이다.
또 27이라는 인수가 어떠한 parameter를 지정해는지 알 수 없기 때문에 이를 명시적으로 할당을 해주어야 한다

발생된 오류를 해결하기위해서는 아래와 같이 순서를 바꾸어주면된다.

def my_profile(age, name = "박세용"):            
	print(f"제 이름은 {name}이고, 나이는 {age} 입니다.")
my_profile(27) 
# 제 이름은 박세용이고, 나이는 27입니다.

위치 인수(positional arguments)와 가변 인수(variable length arguments)의 위치

먼저 위치인수와 가변인수가 무엇인지 간단하게 알아보자.

  • 위치 인수(positional arguments): 함수에 인수를 순서대로 넣는 방식

    위치 인수 예시

def my_profile(name,age):
	print(f"이름 : {name}, 나이: {age}")

 my_profile("박세용", 27)
# 이름 : 박세용, 나이 : 27
  • 가변 인수(variable length arguments) : 인수의 개수가 정해지지 않은 방식

    가변 인수 예시

def my_profile(*args):
	for i in args:
    	print(i)

my_profile("박세용", "나이 : 27","주소 : 경기도")
#  박세용
#  나이 : 27
#  주소 : 경기도
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)

위의 함수를 실행하면 오류가 발생한다.
Traceback (most recent call last): File "<pyshell#20>", line 1, in <module> func_param_with_var_args("정우성", "01012341234", "seoul", 20) TypeError: func_param_with_var_args() missing 1 required keyword-only argument: 'age'

에러가 발생한 이유는 parameter의 순서에 있다.
positional arguments 가 먼저오고 그 다음에 variable length arguments 가 와야 한다.

에러를 해결하기위해 age*args의 순서를 바꾼다음 다시 코드를 살펴보면

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("정우성", "01012341234", "seoul", 20)
# name=정우성
# args=('seoul', 20)
# age=01012341234

위와 같이 오류가 해결된것을 볼 수있다.

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

  • 가변 키워드 인수(variable length keyword arguments) = **kwargs
  • **kwargs는 키워드 = 값 형태로 함수를 호출하고, dict 형태 'key' : 'value' 로 함수 내부에 전달한다.
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")

# 오류 발생 -> `SyntaxError: invalid syntax`

위의 함수 정의시에 가변 키워드 인수가 포함이 되어있다.
보는 것과 같이 가변 키워드 인수가 가운데에 위치하게 되니 함수 정의 자체가 되지 않는다.

name 은 Regulal Positional Arguments,
age도 Regular Positional Arguments,
**kwargs는 Variable Length Keyword Arguments,
address는 eyword-Only Arguments With Defauls.

따라서 variable length keyword argumentsKeyword-Only Arguments With Defauls보다 앞에 있으므로 오류가 발생한다.

위의 오류를 해결하기 위해서는 가변키워드 인수를 마지막으로 보내주어야 한다.

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

위치 인수와 키워드 가변 키워드 인수 (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")

# 오류 발생 : `SyntaxError: invalid syntax`

함수를 정의할수없다는 오류가 발생한다.

우선 파라미터들이 어떻게 되어있는지 부터 먼저 확인해보면

age는 Regular Positional Arguments,
name="아이유" 는 Default Arguments,
*args는 Variable Length Positional Arguments,
address는 Non-Default Keyword-Only Arguments
**kwargs는 Variable Length Keyword Arguments,

이렇게 되어있다.
정상적으로 출력하기위해 위에서 오류를 해결한 사례들을 생각하며 각 파라미터의 위치를 우선순위대로 바꾸어 보았다.

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

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

파라미터의 순서를
age -> name="아이유"->*args->address->**kwargs
으로 바꾸어주니
정상출력되는것을 확인할 수 있다.


.Reference
https://velog.io/@wind1992/%EA%B0%80%EB%B3%80%EC%9D%B8%EC%88%98%EC%99%80-%EA%B0%80%EB%B3%80%ED%82%A4%EC%9B%8C%EB%93%9C-%EC%9D%B8%EC%88%98
https://wikidocs.net/84426
https://opentutorials.org/module/4811/28493
https://devpouch.tistory.com/82

profile
# 불편함을 편리함으로 바꾸고싶은 주니어 Back-end 개발자

0개의 댓글