트랙
/
Python
Python
/
학습 과정
/
함수 인자
함수

함수 인자 에서 Python

{other: "%{count}개의 연습 문제"}

함수 인자 소개

함수 인자의 기본 내용은 함수 개념에서 확인할 수 있어요.

매개변수 이름

매개변수 이름은 변수 이름과 마찬가지로 문자나 밑줄로 시작해야 하고, 문자, 밑줄, 숫자를 포함할 수 있어요. 매개변수 이름에는 공백이나 문장 부호가 들어가면 안 돼요.

위치 인자

위치 인자는 함수에 전달되는 값으로, 그 값을 받는 매개변수와 같은 순서로 전달돼요. 위치 인자는 매개변수 이름을 사용해서 전달할 수도 있어요:

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로 변환하는 연산자예요.

Note

튜플을 언패킹해 본 적이 있다면, *args의 *가 헷갈릴 수 있어요. 매개변수 정의에서 *는 튜플을 푸는 대신, 하나 이상의 위치 인자를 튜플로 변환해요.

* 연산자는 상황에 따라 다르게 동작하기 때문에 오버로드되었다고 해요. 예를 들어 *는 곱셈에 쓰이고, 언패킹에 쓰이며, 임의 개수의 위치 매개변수를 정의하는 데에도 쓰여요.

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)
GitHub에서 편집 링크가 새 창이나 탭에서 열려요