[Python]Function Parameter, Argument 에 대하여
SW개발/Python

[Python]Function Parameter, Argument 에 대하여

파이썬은 매우 자유도가 높은 언어이다. 따라서 함수를 사용하면서 인자값에 대해 큰 신경을 쓰지 않아도 에러 없이 편하게 프로그래밍을 할 수 있다. 하지만 그러다가 non-default argument follows default argument 라는 에러를 마주하게 되었고, 이번 기회에 파이썬 함수의 Paramter, Argument의 처리에 관해서 자세히 공부해보기 위해 포스팅을 작성하게 되었다.

 

https://docs.python.org/ko/3.10/glossary.html 의 parameter, argument 참조.

 

용어집 — Python 3.10.4 문서

같은 형의 두 인자를 수반하는 연산이 일어나는 동안, 한 형의 인스턴스를 다른 형으로 묵시적으로 변환하는 것. 예를 들어, int(3.15)는 실수를 정수 3으로 변환합니다. 하지만, 3+4.5 에서, 각 인자

docs.python.org

https://peps.python.org/pep-0570/

 

PEP 570 – Python Positional-Only Parameters | peps.python.org

Python originally supported positional-only parameters. Early versions of the language lacked the ability to call functions with arguments bound to parameters by name. Around Python 1.0, parameter semantics changed to be positional-or-keyword. Since then,

peps.python.org

https://peps.python.org/pep-3102/

 

PEP 3102 – Keyword-Only Arguments | peps.python.org

PEP 3102 – Keyword-Only Arguments Author Talin Status Final Type Standards Track Created 22-Apr-2006 Python-Version 3.0 Post-History 28-Apr-2006, 19-May-2006 Table of Contents This PEP proposes a change to the way that function arguments are assigned to

peps.python.org

 

Function Parameter (매개변수, 인수)

Parameter란 함수 정의에서 함수가 받을 수 있는 Arguments를 지정하는 이름 붙은 엔티티이다. 총 5가지 종류의 Parameter가 있다.

 

1. positional-or-keyword

positional, keyword arguments로 전달될 수 있는 인자를 지정하고, 이것이 파이썬 기본 형태의 파라미터이다. 다음의 foo, bar와 같다.

def func(foo, bar=None): ...

 

2. positional-only

위치로만 제공될 수 있는 인자를 지정한다. 위치 전용 매개변수는 함수 정의의 매개변수 목록에 / 문자의 앞에 정의할 수 있다. 다음의 posonly1, posonly2와 같다.

def func(posonly1, posonly2, /, positional_or_keyword): ...

 

3. keyword-only 

키워드로만 제공될 수 있는 인자를 지정한다. keyword only 매개변수는 함수 정의의 매개변수 목록에서 앞에 하나의 var-positional 매개변수* 를 그대로 포함해서 정의할 수 있다. 다음의 kw_only1, kw_only2와 같다.

def func(arg, *, kw_only1, kw_only2): ...

 

4. var-positional

(다른 매개변수들에 의해서 이미 받아들여진 위치 인자들에 더하여) 제공될 수 있는 위치 인자들의 임의의 시퀀스를 지정한다. 이런 매개변수는 매개변수 이름에 * 를 앞에 붙여서 정의될 수 있다. 다음의 args와 같다.

def func(*args, **kwargs): ...

 

5. var-keyword

(다른 매개변수들에 의해서 이미 받아들여진 키워드 인자들에 더하여) 제공될 수 있는 임의의 개수 키워드 인자들을 지정한다. 이런 매개변수는 매개변수 이름에 ** 를 앞에 붙여서 정의될 수 있다. 다음의 kwargs와 같다.

def func(*args, **kwargs): ...

 

Python Func Paramter

 

함수에 variable한 paramter까지 포함한다면 최종적으로는 아래와 같은 순서(형태)가 된다.

def func(
    posonly1, posonly2, /, a, b=10, *, keyword_only1, keyword_only2, *arg, **kwargs
): ...

 

Function Arguments (인자)

Argument 란 함수를 호출할 떄 함수로 전달되는 값이다. 두 종류의 인자가 존재한다.

 

1. keyword argument

함수 호출 때 식별자가 앞에 붙은 인자 (ex: today=) 또는 ** 를 앞에 붙인 딕셔너리로 전달되는 인자이다. 예를 들어, 다음과 같은 leffe() 호출에서 100 과 500 는 모두 keyword argument 이다.

def(today=100, total=500)
def(**{'today': 100, 'total'L 500})


또한, parmteter 이름에 맞추어 값을 넣기 때문에 순서가 바뀌어도 에러가 나지 않고, 어떠한 값을 전달하는지 명확해 가독성도 높다.

 

2. positional argument

keyword argument 가 아닌 인자이다. positional arugments는 인자 목록의 처음에 나오거나 iterable의 앞에 * 를 붙여 전달할 수 있다. 예를 들어, 다음과 같은 호출에서 100 과 500 은 모두 positional argument 이다.

leffe(100, 500)
leffe(*(100, 500))

keyword argument 보다 뒤에 위치할 경우 에러가 발생하기 때문에 주의해야 한다. (ex: leffe(total=500, 100))

 

Parameter Default Value

다음은, 내가 개발하면서 겪었던 오류중의 하나와 함께 이야기 해보겠다. 

default argument의 경우 non-default argument의 앞에 올 수 없다.

해당 내용의 경우 함수를 호출하거나 선언할 때 그럴 수 없다는 것은 이미 알고 있는 사실이었다. 하지만 나의 경우에 pydantic 을 이용하면서 Model Class를 선언하는 과정에서 해당 에러를 겪었기에 약간 당황했었다. 오류 예제 코드를 살펴보자.

# pydantic model error ❌
class Person(BaseModel):
    id: int
    name: str = 'Leffe'
    height: int = 177
    phone: Optional[str]

다음과 같이 모델을 선언할 경우 SyntaxError: non-default argument follows default argument 에러를 맞이하게 된다.

클래스의 경우, __init__() 메서드를 통해 argument가 전달되기 때문에 위의 규칙에 어긋나기 때문에 에러가 발생하는 것이다.

따라서, default argument의 위치를 옮겨 에러를 수정할 수 있었다.

# pydantic model not error ⭕️
class Person(BaseModel):
    id: int
    phone: Optional[str]
    name: str = 'Leffe'
    height: int = 177

 

Python Function Definition, Arguments

 

읽어 주셔서 감사합니다. 공부하면서 정리한 내용이니 틀린 내용이 있을 수 있습니다.  댓글 남겨주시면 감사하겠습니다! :)

 

728x90