python 함수에서 특별한 매개변수 사용법
python에서 함수의 인수는 기본적으로 위치를 기반으로 인수를 전달하거나 명시적으로 키워드를 기반으로 인수를 전달할 수 있습니다.
# 파이썬의 판다스 라이브러리의 코드를 통한 예시
import pandas as pd
pd.Series([5, 2], ['A', 'B']) # 위치 기반 인수 전달
pd.Series(data=[5, 2], index=['A', 'B']) # 키워드 기반 인수 전달
위치를 기반으로 인수를 전달하는 것은 순서에 맞게 인수만 전달하는 것을 의미하고, 키워드 기반으로 인수를 전달하는 것은 매개변수와 함께 명시적으로 인수를 전달합니다.
일반적으로 정의한 파이썬의 함수는 위치 기반과 키워드 기반으로 모두 전달할 수 있습니다만 특별한 매개변수 /와 *가 포함되면 위치 전용 혹은 키워드 전용으로 인수를 전달해야 합니다. 매개변수 /와 *를 기준으로 인수를 전달하는 방식이 정해집니다.
1. 위치 또는 키워드 인수 (Positional-or-Keyword Arguments)
함수 정의에 /와 *가 포함되어 있지 않다면, 인수는 위치 또는 키워드를 통해 전달될 수 있습니다. /와 *가 존재하더라도 / 뒤에 오며 * 앞에 위치한 경우 위치 또는 키워드로 전달될 수 있습니다.
2. 위치 전용 매개변수 (Positional-Only Parameters)
특정 매개변수를 위치 전용으로 지정할 수 있습니다. 위치 전용인 경우 매개변수의 순서가 중요하며, 매개변수를 키워드로 전달할 수 없습니다. 위치 전용 매개변수는 /(슬래시) 앞에 위치하며, /는 위치 전용 매개변수와 나머지 매개변수를 구분하는 역할을 합니다. 함수 정의에 /가 포함되지 않으면 위치 전용 매개변수가 없습니다.
3. 키워드 전용 매개변수 (Keyword-Only Arguments)
* 뒤에 배치된 매개변수는 키워드로만 전달해야 합니다. 즉 매개변수와 함께 인수를 전달해야 합니다.
판다스의 경우
판다스에서는 많은 경우 키워드 전용 매개변수를 사용하도록 정의되어 있습니다. 판다스 구버전은 그렇지 않았지만, 패치를 거듭하면서 점차 키워드 기반으로 바뀌고 있습니다.
판다스 drop 함수의 예를 들어보겠습니다.
판다스 drop 함수의 정의에는 매개변수 *가 존재하기에 * 이후로 존재하는 매개변수는 모두 키워드 기반으로 적용해야 하며 반드시 매개변수와 함께 사용해야 합니다.
여러분의 이해를 돕기 위해 변수 df를 데이터 프레임으로 생성해 보겠습니다.
import pandas as pd
data = {'A': [59, 11, 65, 95], 'B': [63, 87, 22, 87],
'C': [49, 51, 9, 99], 'D': [4, 39, 77, 65]}
df = pd.DataFrame(data)
df에서 A 열을 삭제해 보겠습니다. 만약 매개변수 axis의 키워드를 생략한다면 다음과 같은 에러가 발생합니다.
df.drop('A', 1)
TypeError: DataFrame.drop() takes from 1 to 2 positional arguments but 3 were given
이 에러는 판다스 구버전의 코드를 참고하는 분들에게 자주 발생하는 에러 중 하나입니다. * 이후의 매개변수는 키워드 기반이기에, 매개변수와 반드시 함께 전달해야 하므로 axis 매개변수는 생략하면 안됩니다. 올바른 코드는 다음과 같습니다.
df.drop('A', axis=1)
결론은 * 이후의 인수는 반드시 매개변수와 함께 전달해야 한다는 점입니다.
심화
1. 에러 메세지 해석
TypeError: DataFrame.drop() takes from 1 to 2 positional arguments but 3 were given
위 에러 메세지는 "TypeError: DataFrame.drop()은 1개에서 2개의 위치 기반 인수를 전달받을 수 있지만, 3개가 주어졌습니다." 입니다.
위 drop 함수를 보면 * 이전에 매개변수 labels만 존재하기에 위치 기반 인수는 1개만 전달받을 수 있다고 생각할 수 있으나, 그것은 메서드 형태로 drop 함수를 메서드로 사용했기에 self가 생략된 것입니다. 메서드로 사용하면 1개의 위치 기반 인수를 전달받을 수 있고, 함수로 사용하면 self와 labels 두 개의 위치 기반 인수를 전달받을 수 있기에 1-2개의 위치 기반 인수를 전달받을 수 있는데, 허용 범위를 초과하는 3개의 위치 기반 인수가 입력되었다는 에러 메세지입니다.
2. 판다스의 경우
앞서 설명한 drop 함수와 같이, 판다스의 많은 함수들은 키워드 전용 매개변수를 가지고 있습니다. 이를 주의하시기 바랍니다. 또한, map 함수처럼 위치 기반 전용 매개변수만 허용하는 함수도 있는데, 이런 함수는 해당 함수가 다른 함수의 인수로 전달될 때 매개변수를 함께 전달할 수 없어 apply 함수 등을 사용할 때 lambda 함수로 작성해야 합니다.
# apply 함수의 인수로 map 함수를 전달할 때
df.apply(map, {'A': 1}) # TypeError: map() takes no keyword arguments
df.apply(lambda x: x.map({'A': 1})) # 이 코드처럼 lambda 함수로 작성한다.
참고문헌: https://docs.python.org/3/tutorial/controlflow.html#special-parameters
'여러 가지 이야기 > 코딩 개념 설명' 카테고리의 다른 글
[python] 여러 개의 변수를 반복문으로 생성하는 방법 (0) | 2023.09.05 |
---|---|
매개변수(parameter)와 인수(argument)의 차이 (0) | 2023.05.28 |