Default Argument Values
2.12 기본 인자 값¶
대부분의 경우 사용해도 괜찮습니다.
2.12.1 정의¶
함수의 매개변수 중 일부에 기본값을 설정할 수 있습니다. 예를 들어, def foo(a, b=0): 와 같이 정의하면,
foo가 하나의 인자만으로 호출될 경우, b는 기본값인 0을 갖습니다.
두 개의 인자로 호출되면, b는 전달된 두 번째 인자의 값을 갖습니다.
2.12.2 장점¶
자주 쓰는 함수에는 보통 여러 개의 기본값을 설정하지만, 드물게 이 기본값을 바꾸고 싶을 때가 있습니다.
기본 인자 값을 사용하면 이런 드문 경우마다 매번 새로운 함수를 따로 정의하지 않아도 됩니다.
또한, 파이썬은 메서드나 함수의 오버로딩을 지원하지 않기 때문에, 기본 인자 값은 오버로딩 기능을 "흉내 내는" 간단한 방법이 될 수 있습니다.
2.12.3 단점¶
기본 인자는 모듈이 처음 로드될 때 한 번만 설정됩니다. 따라서 기본값으로 리스트나 딕셔너리 같은 가변 객체를 사용하면, 예상치 못한 문제가 생길 수 있습니다. 함수에서 해당 객체를 수정할 경우(예: 리스트에 항목을 추가하는 경우), 기본값 자체가 변경될 수 있습니다.
2.12.4 권장사항¶
사용해도 괜찮지만, 다음 사항에 주의해야 합니다 :
함수나 메서드를 정의할 때, 가변 객체를 기본 인자 값으로 사용하지 마세요.
# Yes(권장):
def foo(a, b=None):
if b is None:
b = [] # 가변 객체를 기본값으로 직접 설정하는 대신, 함수 내부에서 새로운 리스트를 생성합니다.
# Yes(권장):
def foo(a, b: Sequence | None = None):
if b is None:
b = [] # 기본값으로 None을 설정하고, 필요할 때마다 새로운 리스트를 생성하여 가변 객체 공유 문제를 방지합니다.
# Yes(권장):
def foo(a, b: Sequence = ()): # 빈 튜플은 변경할 수 없는(immutable) 객체이므로 안전하게 사용할 수 있습니다.
...
from absl import flags
_FOO = flags.DEFINE_string(...)
# No(주의):
def foo(a, b=[]): # 기본값으로 리스트를 사용하면, 함수 호출 간에 값이 공유될 위험이 있습니다.
...
# No(주의):
def foo(a, b=time.time()): # `b`가 이 모듈이 로드된 시점을 나타내도록 의도된 것인가요?
...
# No(주의):
def foo(a, b=_FOO.value): # sys.argv가 아직 파싱되지 않았을 수 있습니다.
...
# No(주의):
def foo(a, b: Mapping = {}): # 기본값으로 빈 딕셔너리를 사용하면, 예기치 않은 코드에 전달될 가능성이 있습니다.
...