def greet(name, greeting="Hello"): # greeting 기본값
return f"{greeting}, {name}"
greet("Kim") # "Hello, Kim"
greet("Kim", "Hi") # "Hi, Kim"
greet(name="Kim", greeting="Yo") # 키워드 인자 (순서 무관)
주의점: 기본값으로 가변 객체(list/dict)를 쓰면 안 됨
def bad(lst=[]): # 위험! 모든 호출이 같은 list 공유
lst.append(1)
return lst
bad() # [1]
bad() # [1, 1] ← 예상과 다름
def good(lst=None): # 올바른 패턴
if lst is None:
lst = []
lst.append(1)
return lst
상황 A: 정의할 때 → “남는 거 다 모아담기”
* 일때
def func(*x):
print(x)
func(1, 2, 3)
func 를 부를 때 인자를 1, 2, 3 세 개 넣음
근데 정의에는 변수가 *x 하나뿐
→ 별포가 “들어온 거 다 모아서 x에 담아” 라고 동작
→ 모은 결과로 tuple로 담김
print(x) # (1, 2, 3)
** 일때
def func(**y):
print(y)
func(a=10, b=20)
이번엔 이름=값 형태로 넣음
별 2개는 이 이름=값 짝들을 모아서 y에 담음
→ 모은 결과는 dict
정리(정의):
* → 그냥 값들(1,2,3) 모음 → tuple
** → 이름=값(a=10, b=20) → dict
상황 B: 호출할 때 → “담겨있던 거 도로 펼치기”
반대로, 이미 list나 dict에 값이 담겨 있는데, 그걸 하나씩 꺼내서 함수에 넣고 싶을 때 사용
nums = [1, 2, 3]
print(nums) # 그냥 list 통째로 넘김 -> **[1, 2, 3]** 출력
print(*nums) # 펼쳐서 넘김 -> print(1, 2, 3)과 동일 -> **1 2 3** 출력
dict는 별 2개로 펼침
config = {"sep": "-", "end": "!"}
print("a", "b", **config)
# -> **print("a", "b", sep="-", end="!")**