~25 min · function, def, arguments, kwargs, default
Level 0호기심
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
함수는 first-class 객체
Python 에서 함수는 값이야. 인자로 넘기고, 다른 함수에서 반환하고, list / dict 에 저장하고, 이름에 할당할 수 있어. def f(): pass 는 함수 객체 만들고 이름 f 를 거기 바인딩. 특별한 경우가 아니야 — x = 5 와 같은 종류의 바인딩, 그냥 오른쪽이 함수일 뿐.
네 가지 파라미터 종류 — / 와 * 구분자
Python 파라미터는 positional-only (위치로만 호출, 구분자 /), positional-or-keyword (디폴트 — 둘 다), keyword-only (이름으로만, 구분자 *), variadic — 추가 위치 인자는 *args, 추가 키워드 인자는 **kwargs. 대부분 함수는 positional-or-keyword 만. 라이브러리 작성자는 구분자로 API 모양 잠가.
디폴트 값 — 그리고 또 그 mutable 함정
디폴트 값은 *함수 정의 시점에 한 번* 평가돼. immutable 디폴트 (숫자, 문자열, None, tuple) 면 OK. mutable 디폴트 (list, dict, set) 면 버그 자석 — 같은 객체가 모든 호출에 재사용. 해결책은 None sentinel 패턴 — def f(x=None): if x is None: x = []. lesson 2 에서 봤어. 그만큼 중요해.
*args 와 **kwargs — 양 방향
함수 시그니처에서 *args 는 추가 위치 인자를 tuple 로 패킹, **kwargs 는 추가 키워드 인자를 dict 로 패킹. 호출 사이트에선 * 와 ** 가 *반대로 unpack* — f(*my_list, **my_dict). 같은 문법, 컨텍스트에 따라 반대 의미.
lambda — 작은 익명 함수
lambda x: x * 2 는 한 식짜리 함수. def f(x): return x * 2 와 같지만 인라인. sorted 의 key 인자, 빠른 콜백, 한 번 쓰고 안 쓸 함수 할당에 좋아. 다중 문장 로직을 lambda 로 짜지 마 — def 써.
원칙: 타입 힌트 (typing 트랙에서) 가 함수가 뭘 기대하는지에 대한 최고의 문서. def send(to: str, body: str, *, retry: int = 3) -> bool: 가 60 글자에 docstring 세 단락보다 더 많이 말해줘.
Code
함수는 first-class — 넘기고, 저장하고, 반환·python
def double(x):
return x * 2
def triple(x):
return x * 3
# 인자로
def apply(fn, value):
return fn(value)
print(apply(double, 5)) # 10
print(apply(triple, 5)) # 15
# dict 에 저장
ops = {"x2": double, "x3": triple}
print(ops["x2"](7)) # 14
# 함수에서 함수 반환
def multiplier(n):
def inner(x):
return x * n
return inner
times_5 = multiplier(5)
print(times_5(10)) # 50
네 가지 파라미터 종류 + 구분자·python
# / 가 경계 — 왼쪽은 모두 positional-only
# * 가 경계 — 오른쪽은 모두 keyword-only
def f(p1, p2, /, normal, *, kw1, kw2=10):
return p1, p2, normal, kw1, kw2
# 유효
print(f(1, 2, 3, kw1=4)) # (1, 2, 3, 4, 10)
print(f(1, 2, normal=3, kw1=4, kw2=99)) # (1, 2, 3, 4, 99)
# 무효
try:
f(p1=1, p2=2, normal=3, kw1=4) # p1/p2 는 positional-only
except TypeError as e:
print(e)
try:
f(1, 2, 3, 4) # kw1 은 키워드여야
except TypeError as e:
print(e)
디폴트 값 — mutable 함정·python
# 안 좋음
def bad(item, history=[]):
history.append(item)
return history
print(bad("a")) # ['a']
print(bad("b")) # ['a', 'b'] <- 공유!
# 좋음
def good(item, history=None):
if history is None:
history = []
history.append(item)
return history
print(good("a")) # ['a']
print(good("b")) # ['b'] <- 새 list
함수 report(title, /, *items, sep=' | ', limit=None, **meta) 작성 — title 은 positional-only, items 는 추가 위치 인자 모음, sep/limit 는 keyword-only with 디폴트, meta 는 나머지 모음. 함수는 title 출력 → 최대 limit 개 (None 이면 전체) item 을 sep 로 join → meta 를 key=value 라인들. 최소 4 가지 호출로 테스트 — report("a", 1, 2, 3, limit=2, color='red') 포함.
Progress
Progress is local-only — sign in to sync across devices.