함수와 파라미터, 아규먼트에 관한 고찰

jinatra·2021년 8월 6일
1

Python

목록 보기
3/15
post-thumbnail

함수(function)와 파라미터(parameter), 아규먼트(argument - 인수)에 관한 고찰


Parameters & Arguments (매개변수 & 인수)

parameter를 통해 함수의 입력값을 정의하고, argument를 통해 함수 호출 시 출력

  • Parameter → 함수에 입력으로 전달된 값을 받는 변수
  • Arguments → 함수를 호출할 때 함수에 전달하는 입력값
def player_of_the_match(name):
    print('Player of the match is... ' + name + '!')

player_of_the_match('Tierny')


# Output: Player of the match is... Tierny!

# name → parameter (매개변수)
# Tierny → argument (인수)

Default Value Parameter

디폴트 매개 변수

함수에 변수를 지정해줄 때, 기본이 되는 default 값을 설정
후에 해당 변수에 대한 인수가 할당되지 않았을 때 default값으로 설정된 변수가 출력

def function(x, y = 2):
    print(x, y)

a = function(21, 22)
b = function(20)


# Output
21 22 # >> x, y 모두에 인수가 할당되었으므로 할당값 출력
20 2  # >> x에만 인수가 할당되었고, y엔 별다른 인수가 없으므로 default로 설정했던 2가 출력됨

Default Value Parameter 와 Non-Default Value Parameter의 순서

우선순위 : 논디폴트 매개변수 > 디폴트 매개변수
순서 : 논디폴트 매개변수 - 디폴트 매개변수

디폴트 매개변수와 논디폴트 매개변수 중에선 누가 먼저 와야할까?
어찌보면 어렵지만 생각해보면 간단하다.

함수를 정의할 때 매개변수는 반드시 설정해줘야 한다. 일반적인 매개변수는 Non-Default Value Parameter이므로 필수적으로 설정해줘야 하지만 Default Value Parameter는 그렇지 않다.

디폴트 매개변수를 먼저 설정해버리게 되면, 초기에 설정한 인수는 자기가 어디에 할당되어야 하는지 모르기 때문

# 논디폴트 매개변수를 먼저, 디폴트 매개변수를 나중에 설정 (YES!)
def function(x, y = 2, z = 3):
    print(x, y, z)

ex_1 = function(10)
ex_2 = function(10, 20)
ex_3 = function(10, 20, 30)


# Output
10, 2, 3    # x가 논디폴트 매개변수, y와z는 디폴트 매개변수
10, 20, 3   # x,y가 논디폴트 매개변수, z는 디폴트 매개변수
10, 20, 30  # x, y, z가 논디폴트 매개변수
# 논디폴트 매개변수를 나중에, 디폴트 매개변수를 먼저 설정 (NO!)

def function(x = 1, y, z):
    print(x, y, z)

ex_1 = function(10)
ex_2 = function(10, 20)
ex_3 = function(10, 20, 30)


# Output
SyntaxError: non-default argument follows default argument

*args (가변인수 - variable length arguments) 에 관한 고찰

*args

새로운 걸 배울때 한국어로 변형된 단어로 익히게 되면 헷갈릴 때가 많아 가급적 원문을 사용하려고 한다.
하지만 가변인수의 경우엔 한국어가 더 이해가 쉬울것 같다.
가변인수란? 말 그대로 변할 수 있는 인수란 얘기다.
즉 사용자가 임의로 집어넣을 수 있는 변수란 얘기지

일반적으로 *args 라고 쓰지만, * 뒤에 어떤게 와도 상관없다.
*hiphop, *love, *munequita 등 무엇이든 가능하다.

한국어 그대로 '변할 수 있는', 영어로 봐도 'variable length'(다양한 길이의)이기에
매개변수를 정의할 때 중간에 오게 되면 Error를 불러일으킬 수 있다.

아래 예시를 보자.

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)


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

잘은 모르겠지만 '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("정우성", 20, "01012341234", "seoul",)


# Output
name=정우성
args=('01012341234', 'seoul')
age=20


**kargs (키워드 가변인수 - variable length keyword arguments) 에 관한 고찰

**kargs

가변인수 앞에 키워드가 붙었다.
내가 배운거 중에 key가 들어간게 뭐가있을까 생각하니 dictionary가 생각났다.

찾아보니

  • 가변인수 - 전달받은 임의의 개수의 인자를 tuple 형태로 저장
  • 키워드 가변인수 - 전달받은 임의의 개수의 인자를 dictionary 형태로 저장

이라고 한다.
가변인수와 똑같이 **kargs 말고도 다양한 이름으로 생성 가능하다.
(**rock, **peace, **jazz 등..)

아래 예시를 보자.

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


# Output
    def func_param_with_kwargs(name, age, **kwargs, address=0):
                                                    ^
SyntaxError: invalid syntax

address 위치가 이상하다고 하는거 같다.
위의 로직과 동일한 이유로 **kargs의 위치를 뒤로 옮겨보면..

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


# Output
name=정우성
age=20
kwargs={'mobile': '01012341234'}
address=seoul


각 인자들간의 우선순위

함수를 정의할 때, 위에서 배운 인자들이 반드시 순서대로 선언이 되어야만 정상적으로 구동이 된다.
인자는 크게 위치, 가변, 가변키워드 세개로 나눌 수 있을 것 같다.

아래 예시를 보자.

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


# Output
    def mixed_params(name="아이유", *args, age, **kwargs, address):
                                                             ^
SyntaxError: invalid syntax

위치인자(Positional argument)가 제일 앞에 와야하므로 age를 제일 앞에 둬보자.

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


# Output
    def mixed_params(age, name="아이유", *args, **kwargs, address):
                                                             ^
SyntaxError: invalid syntax

자세히 보니 뒤에 address 파라미터도 있다. 한번 옮겨보자.

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


# Output

    mixed_params(20, "정우성", "01012341234", "male", mobile="01012341234", address="seoul")
TypeError: mixed_params() got multiple values for argument 'address'

이젠 인수들의 설정이 잘못되어있는듯 하다.
파라미터 순서에 맞게 아규먼트들을 정리해주면,

def mixed_params(age, address, name="아이유", *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, "seoul", "정우성", "01012341234", "male", mobile="01012341234")


# Output

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

옳게 출력되는걸 볼 수 있다.




Take Away

인수의 이름

검색하면서 알게된건데 argument들을 인자, 인수 등 자기 입맛에 맞게 부르는 곳들이 많은 것 같다.
나도 블로깅 중에 인자를 쓸 때도 있었고 인수를 쓸 때도 있었다.
그래서 나는 앞으로 그냥 parameter을 파라미터, arguement를 아규먼트로 부르는게 속 편할 듯 하다..


파라미터의 순서

논디폴트 - 디폴트 - 가변 - 가변 키워드
순서로 이해를 해야할 듯 하다.


*args**kargs는 왜 가변 인수, 가변 키워드 인수라고 부르나?

내 개인적인 생각인데, 아마 이런거 같다.
파라미터는 기본적으로 디폴트, 논디폴트 두개의 값을 갖는다.
그러나 가변 인수나 가변 키워드 인수의 경우엔 추후 입력이 되는 것에 따라 각각 튜플, 딕셔너리의 성질을 가지므로 본질적으론 아규먼트(인수)와 동일한 로직을 가진다고 볼 수 있을 것이다.
이게 이름으로 부르려니 좀 애매해지는 것이지, 머릿속으로 생각해보면 꽤 간단한거 같다.

profile
으악

1개의 댓글

comment-user-thumbnail
2021년 8월 6일

헷갈리는 개념 잘 정리하셨네요!!

답글 달기