함수 인자의 기본 내용은 함수 개념에서 확인할 수 있어요.
매개변수 이름은 변수 이름과 마찬가지로 문자나 밑줄로 시작해야 하고, 문자, 밑줄, 숫자를 포함할 수 있어요. 매개변수 이름에는 공백이나 문장 부호가 들어가면 안 돼요.
위치 인자는 함수에 전달되는 값으로, 그 값을 받는 매개변수와 같은 순서로 전달돼요. 위치 인자는 매개변수 이름을 사용해서 전달할 수도 있어요:
def concat(greeting, name):
return f"{greeting}{name}"
# Passing data to the function by position.
print(concat("Hello, ", "Lilly"))
#-> Hello, Lilly
# Passing data to the function using the parameter name.
print(concat(name="Glenn", greeting="Hello, "))
#-> Hello, Glenn
concat을 처음 호출할 때는 인자를 위치로 전달해요.
두 번째 호출에서는 인자를 이름으로 전달하는데, 이렇게 하면 순서를 바꿀 수 있어요.
위치 인자는 이름으로 전달한 인자 (이른바 키워드 인자. 가변 위치 매개변수나 **kwargs와 혼동하면 안 돼요) 뒤에 올 수 없어요.
이런 인자 조합은:
print(concat(greeting="Hello, ", "Gregor"))
이런 오류가 나요:
SyntaxError: positional argument follows keyword argument
함수 호출에서 위치 전용 인자만 받도록 하려면 매개변수 목록에 / 연산자를 사용하면 돼요:
# Parameters showing a position-only operator.
def concat(greeting, name, /):
return f"{greeting}{name}"
print(concat("Hello, ", "Ginnie"))
#-> Hello, Ginnie
# Call to the function using keyword arguments.
print(concat(name="Franklin", greeting="Hello, "))
Traceback (most recent call last):
print(concat(name="Franklin", greeting="Hello, "))
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting, name'
키워드 인자는 함수를 호출할 때 매개변수 이름을 사용해요. 위치로 나타낼 수도 있어요:
def concat(greeting, name):
return f"{greeting}{name}"
# Function call using parameter names as argument keywords.
print(concat(name="Eliza", greeting="Hello, "))
#-> Hello, Eliza
# Function call with positional data as arguments.
print(concat("Hello, ", "Tim"))
#-> Hello, Tim
함수 호출에서 키워드 전용 인자만 받도록 하려면 매개변수 목록에 * 연산자를 사용하면 돼요:
# Function definition requiring keyword-only arguments.
def concat(*, greeting, name):
return f"{greeting}{name}"
# Keyword arguments can be in an arbitrary order.
print(concat(name="Kimmie", greeting="Hello, "))
#-> Hello, Kimmie
# Calling the function with positional data raises an error.
print(concat("Hello, ", "Coleen"))
Traceback (most recent call last):
print(concat("Hello, ", "Coleen"))
TypeError: concat() takes 0 positional arguments but 2 were given
하나 이상의 인자에 대한 기본값은 매개변수 목록에서 지정할 수 있어요. 그러면 필요할 때 함수를 더 적은 인자로 호출할 수 있어요. 함수를 호출할 때 새 인자 값을 넘기면 기본값을 덮어쓸 수 있어요:
# Function with default argument values.
def concat(greeting, name="you", punctuation="!"):
return f"{greeting}, {name}{punctuation}"
print(concat("Hello"))
#-> Hello, you!
# Overriding the default values
print(concat("Hello", name="Polly", punctuation="."))
#-> Hello, Polly.
매개변수 정의에 /나 * 연산자를 사용하지 않으면 인자는 위치로도 키워드로도 전달할 수 있어요.
또는 위치-키워드 인자를 왼쪽의 위치 전용 매개변수와 오른쪽의 키워드 전용 매개변수 사이에 둘 수 있어요:
# Position-only argument followed by position-or-keyword, followed by keyword-only.
def concat(greeting, /, name, *, ending):
return f"{greeting}{name}{ending}"
print(concat("Hello, ", "Mark", ending="!"))
#-> Hello, Mark!
print(concat("Hello, ", name="Rachel", ending="!"))
#-> Hello, Rachel!
print(concat(greeting="Hello, ", name="JoJo", ending="!"))
Traceback (most recent call last):
print(concat(greeting="Hello, ", name="JoJo", ending="!"))
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting'
*args코드 예제에서는 흔히 다음과 비슷한 함수 정의를 사용해요:
def my_function(*args, **kwargs):
# code snipped
*args는 두 부분으로 이루어진 이름으로, 개수가 정해지지 않은 여러 개의 위치 인자를 담는 tuple을 나타내요. 다른 말로 variadic argument라고도 해요.
args는 인자로 이루어진 tuple에 붙인 이름인데, my_args, arguments 등 다른 유효한 파이썬 이름이어도 돼요.
*는 여러 인자를 하나로 묶어 tuple로 변환하는 연산자예요.
tuple은 반복할 수 있기 때문에 args는 이터러블을 받는 다른 함수에 전달할 수 있어요.
*args는 흔히 **kwargs와 함께 쓰이지만, 반드시 그래야 하는 것은 아니에요:
def add(*args):
# args is passed to the sum function, which iterates over it.
return sum(args)
print(add(1, 2, 3))
#-> 6
*args가 하나 이상의 위치 인자 뒤에 오면, *args에는 위치 인자를 빼고 남은 값이 들어가요:
def add(first, *args):
# first will be 1, leaving the values 2 and 3 in *args
return first + sum(args)
print(add(1, 2, 3))
#-> 6
*args 뒤에 하나 이상의 기본 인자가 정의되면, 그것들은 *args 값과 별개예요:
def add(first, *args, last=0):
return first + sum(args) + last
print(add(1, 2, 3))
#-> 6
print(add(1, 2, 3, last=4))
#-> 10
# This uses the unpacking operator * to separate the list elements into positional arguments.
# It does not have the same behavior as the * (packing) in *args.
print(add(*[1, 2, 3]))
#-> 6
인자가 이미 iterable (예를 들어 tuple이나 list) 안에 들어 있다면, 임의 개수의 개별 인자를 받는 함수에 전달하기 전에 언패킹해야 해요.
이때는 언패킹 연산자인 *를 사용해요.
이 문맥에서 *는 컨테이너를 개별 요소로 풀어내고, 그 요소들은 다시 *args에 의해 tuple로 변환돼요.
위치 인자만 사용하는 경우, 언패킹 결과는 정의된 형식 매개변수의 수와 같은 수의 인자가 되어야 해요.
add에 전달한 배열을 언패킹하지 않으면 프로그램에서 오류가 발생해요:
def add(first, *args, last=0):
return first + sum(args) + last
print(add([1, 2, 3]))
Traceback (most recent call last):
print(add([1, 2, 3]))
return first + sum(args) + last
TypeError: can only concatenate list (not "int") to list
**kwargs**kwargs는 두 부분으로 이루어진 이름으로, 개수가 정해지지 않은 여러 개의 키-값 쌍 인자를 나타내요.
kwargs는 인자 묶음에 붙인 이름이며, my_args, arguments 등 다른 이름이어도 돼요.
**는 이름이 있는 인자 묶음을 {argument name: argument value} 쌍으로 이루어진 dictionary로 변환해요.
딕셔너리는 반복할 수 있기 때문에 kwargs는 이터러블을 받는 다른 함수에 전달할 수 있어요.
**kwargs는 흔히 *args와 함께 쓰이지만, 반드시 그래야 하는 것은 아니에요:
def add(**kwargs):
return sum(kwargs.values())
print(add(one=1, two=2, three=3))
#-> 6
kwargs 딕셔너리의 values를 반복하기 위해 dict.values() 메서드가 호출된다는 점에 주의해요.
딕셔너리를 반복할 때는 기본적으로 _keys_를 순회하므로, dict.values()를 명시적으로 지정해야 해요:
def concat(**kwargs):
# Join concatenates the tuples from `kwargs.items()`
return " ".join((str(item) for item in kwargs.items()))
print(concat(one=1, two=2, three=3))
#-> ('one', 1) ('two', 2) ('three', 3)