*args은 추가 위치 인수를 튜플로 수집합니다.**kwargs은 추가 키워드 인수를 사전으로 수집합니다.*과**가 중요하므로 이름은 단지 관례일 뿐입니다.- 함수를 호출할 때 목록이나 사전도 같은 방식으로 압축해제됩니다.
조만간 def handler(*args, **kwargs)과 같은 함수를 읽고 그것이 무엇을 받아들이는지 궁금할 것입니다. Python *args 및 **kwargs를 사용하면 함수가 유연한 수의 인수를 사용할 수 있습니다. 데코레이터, 래퍼 및 많은 라이브러리 API를 지원합니다.
이 가이드에서는 Python이 함수 호출 방법을 제어할 수 있는 새로운 방법과 함께 양방향으로 작동하는 방법을 다룹니다. Python 3.13에서 각 예제를 실행했으며 표시된 출력은 해당 실행에서 나온 것입니다.
*args가 하는 일
별표 하나로 작성된 매개변수는 추가 위치 인수를 튜플로 수집합니다.
def total(*args):
print(type(args).__name__, args)
return sum(args)
print(total(1, 2, 3))
# tuple (1, 2, 3)
# 6
print(total())
# tuple ()
# 0
인수가 없으면 단순히 빈 튜플을 얻게 되므로 함수는 계속 작동합니다. 이름 args은 관례입니다. *numbers는 동일하게 작동하며 더 설명적인 이름이 더 나은 경우가 많습니다.
**kwargs가 하는 일
별 두 개는 추가 키워드 인수를 사전에 수집합니다.
def describe(**kwargs):
print(type(kwargs).__name__, kwargs)
describe(name="Asha", city="Pune")
# dict {'name': 'Asha', 'city': 'Pune'}
이는 일반적인 사전이므로 반복할 수 있고 get()를 사용하여 키를 찾아 전달할 수 있습니다. 키는 전달된 순서를 유지합니다.
매개변수 순서
다양한 매개변수를 혼합할 때 Python에는 특정 순서가 필요합니다.
- 일반 위치 매개변수
*인수- 키워드 전용 매개변수
**크와르그
def order(item, qty=1, *extras, priority=False, **notes):
print(item, qty, extras, priority, notes)
order("pen")
# pen 1 () False {}
order("pen", 2, "gift wrap", "card", priority=True, note="leave at door")
# pen 2 ('gift wrap', 'card') True {'note': 'leave at door'}
공지사항 priority. *extras 뒤에 오기 때문에 이름으로만 설정할 수 있으므로 길을 잃은 위치 인수로 인해 실수로 설정할 수 없습니다. **kwargs을 더 일찍 넣는 것은 허용되지 않으며 테스트에서는 “인수는 var-keyword 인수 뒤에 올 수 없습니다.”라는 SyntaxError를 발생시켰습니다.
전화할 때 포장 풀기
동일한 별이 호출 사이트에서 반대로 작동합니다. 별 하나는 목록이나 튜플을 위치 인수로 퍼뜨리고, 별 두 개는 사전을 키워드 인수로 퍼뜨립니다.
nums = [4, 5, 6]
total(*nums) # same as total(4, 5, 6) -> 15
settings = {"name": "Ben", "city": "Delhi"}
describe(**settings) # same as describe(name="Ben", city="Delhi")
압축 풀기는 *args 및 **kwargs를 사용하는 기능뿐만 아니라 모든 기능에서 작동합니다. 이는 구성이 사전으로 도착할 때 편리합니다.
def connect(host, port, timeout=5):
return f"{host}:{port} (timeout {timeout})"
connect(**{"host": "db.local", "port": 5432})
# 'db.local:5432 (timeout 5)'
connect(**{"host": "db.local", "port": 5432, "ssl": True})
# TypeError: connect() got an unexpected keyword argument 'ssl'
그 오류는 유용합니다. **kwargs이 없는 함수는 알 수 없는 옵션을 거부하므로 설정 이름의 오타는 조용히 무시되는 대신 큰 소리로 실패합니다.
키워드 전용 인수
서명에 이름이 없는 *은 “이후의 모든 내용은 키워드로 전달되어야 함”을 의미합니다.
def make_user(name, *, admin=False):
return name, admin
make_user("Asha", admin=True)
# ('Asha', True)
make_user("Asha", True)
# TypeError: make_user() takes 1 positional argument but 2 were given
이는 부울 플래그를 보호하는 좋은 방법입니다. make_user("Asha", True)과 같은 호출은 독자가 True의 의미를 추측하게 만듭니다. admin=True을 요구하면 모든 호출이 자명해집니다.
위치 전용 인수
Python 3.8부터 /은 위치로만 전달될 수 있는 매개변수를 표시합니다.
def area(width, height, /):
return width * height
area(3, 4) # 12
area(width=3, height=4)
# TypeError: area() got some positional-only arguments
# passed as keyword arguments: 'width, height'
누구도 이름에 의존할 수 없기 때문에 이를 통해 라이브러리는 나중에 다른 사람의 코드를 손상시키지 않고 해당 매개변수의 이름을 바꿀 수 있습니다. 여러 내장 기능이 이런 방식으로 작동합니다. 예를 들어, len(obj=[1])은 작동하지 않습니다.
팁: 전체 패턴은 def f(pos_only, /, normal, *, kw_only)입니다. 세 가지가 모두 필요한 경우는 거의 없지만 /과 *의 의미를 알면 문서와 라이브러리 서명을 읽는 데 도움이 됩니다.
데코레이터 및 래퍼
이것이 두 가지를 함께 사용하는 주요 실제 이유입니다. 래퍼는 원래 함수가 취하는 인수가 무엇이든 받아들이고 이를 변경하지 않고 전달해야 하는 경우가 많습니다.
import functools, time
def timed(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
print(f"{func.__name__} took {time.perf_counter() - start:.4f}s")
return result
return wrapper
@timed
def slow_add(a, b, delay=0.01):
time.sleep(delay)
return a + b
print(slow_add(2, 3, delay=0.02))
# slow_add took 0.0205s
# 5
래퍼는 slow_add의 매개변수를 전혀 알 필요가 없으므로 모든 기능에서 작동합니다. 타이밍 수치는 약간 다를 수 있습니다. Python 데코레이터 가이드에서는 functools.wraps 및 기타 세부 사항을 설명합니다.
병합 옵션
**은 사전 리터럴 내에서도 작동하며, 기본값 위에 재정의를 적용하는 깔끔한 방법을 제공합니다.
defaults = {"theme": "light", "lang": "en"}
def build(**overrides):
return {**defaults, **overrides}
build(theme="dark")
# {'theme': 'dark', 'lang': 'en'}
나중에 키가 우선하므로 재정의가 기본값을 대체합니다. 하위 클래스도 super().__init__(*args, **kwargs)에서처럼 이 패턴을 사용하여 상위 클래스에 추가 인수를 전달합니다. super()에 대한 자세한 내용은 Python 클래스 및 개체를 참조하세요.
치트 시트
| 구문 | 어디에 | 의미 |
|---|---|---|
데프 f(*인수) |
정의 | 추가 위치 인수를 튜플로 수집 |
def f(**kwargs) |
정의 | 추가 키워드 인수를 사전으로 수집합니다. |
데프 f(a, *, b) |
정의 | b은 키워드 전용입니다. |
def f(a, /, b) |
정의 | a은 위치 전용입니다. |
f(*items) |
전화 | 시퀀스를 위치 인수로 확산 |
f(**options) |
전화 | 사전을 키워드 인수로 확산 |
{**아, **비} |
리터럴 | 사전 병합 |
[*a, *b] |
리터럴 | 반복 가능한 항목을 목록으로 결합 |
피해야 할 때
유연성에는 대가가 따릅니다. def create(**kwargs)로 정의된 함수는 독자에게 어떤 옵션이 있는지 알려주지 않으며 편집자는 해당 옵션을 자동 완성할 수 없습니다. 오타는 오류가 발생하기 전에 여러 레이어를 조용히 통과할 수 있습니다.
따라서 함수에 필요한 것이 무엇인지 알면 명시적인 매개변수를 선호하세요. 래퍼, 데코레이터, 인수를 다른 함수로 전달 또는 total(*numbers)과 같은 실제 가변 길이 입력 등 유연성이 정말로 필요한 경우 *args과 **kwargs를 사용하세요. 함수에 명명된 옵션이 많이 필요한 경우 dataclass가 더 명확할 수도 있습니다.
일반적인 실수
변경 가능한 기본값 사용
이것은 별에 관한 것이 아니라 별 근처에 자주 나타납니다. 기본값은 함수가 정의될 때 한 번 생성된 후 호출 간에 공유됩니다.
def bad(items=[]):
items.append(1)
return items
print(bad(), bad())
# [1, 1] [1, 1]
두 호출 모두 매우 동일한 목록을 반환했으며 그 목록에는 두 개의 항목이 포함되었습니다. items=None을 사용하고 함수 내부에 새 목록을 만듭니다.
기타 오류
- 포장 풀기를 잊어버렸습니다.
total(nums)를 호출하면 세 개의 숫자가 아닌 하나의 목록이 전달됩니다.total(*nums)을 쓰세요. - 오타를 삼키는 중입니다.
**kwargs를 허용하지만 알 수 없는 키를 무시하는 함수는 철자가 틀린 옵션을 숨깁니다. 검증하거나 피하세요**kwargs. - 동일한 인수를 두 번 전달합니다.
f(1, **{"a": 2}), 여기서a이 첫 번째 매개변수인 경우 “다중 값” 오류가 발생합니다. - 래퍼로 전달하지 않습니다.
func(args, kwargs)를 호출하면 튜플과 사전이 전달됩니다. 올바른 형식은func(*args, **kwargs)입니다.
*args 및 **kwargs에 대한 힌트를 입력하세요.
*args과 **kwargs의 힌트를 입력하면 전체 컬렉션이 아닌 각 개별 값을 설명합니다. 이는 많은 사람들을 놀라게 합니다.
def total(*prices: float) -> float:
return sum(prices) # prices is tuple[float, ...]
def tag(**attrs: str) -> str:
return " ".join(f'{k}="{v}"' for k, v in attrs.items()) # dict[str, str]
total(1.5, 2.5) # 4.0
tag(id="x", role="button") # id="x" role="button"
여기서 prices은 부동 소수점의 튜플로 처리되고 attrs는 문자열 사전으로 처리됩니다. 키워드 인수의 유형이 다른 경우 Python 3.12에서는 Unpack와 결합된 TypedDict이라는 정확한 옵션을 추가했습니다.
from typing import TypedDict, Unpack
class Options(TypedDict, total=False):
timeout: float
retries: int
def fetch(url: str, **opts: Unpack[Options]) -> None: ...
그런 다음 mypy 또는 Pyright와 같은 유형 검사기는 fetch(url, retries="3") 또는 철자가 틀린 옵션 이름을 거부할 수 있습니다. 이는 일반 **kwargs에서는 절대 수행할 수 없는 일입니다. 그러나 런타임 동작은 변경되지 않습니다. Python 3.13에서 fetch("u", retries="3")을 실행했을 때 Python 자체는 유형 힌트를 적용하지 않기 때문에 아무런 문제 없이 실행되었습니다.
**kwargs에 대해 허용되는 키의 긴 목록을 문서화하고 있는 경우 이를 명시적인 키워드 전용 매개변수로 바꾸는 것을 고려해 보십시오. 그런 다음 편집자는 자동 완성 기능을 사용할 수 있으며 실수는 즉시 발견됩니다.
마무리
두 가지 방향을 기억하세요. 정의에 따르면 스타는 수집됩니다. 통화 중에 그들은 짐을 푼다. 호출을 더 명확하게 하려면 키워드 전용 인수를 추가하고 인수를 실제로 전달하는 코드용으로 **kwargs을 예약하세요. 연습하려면 모든 호출의 인수를 기록하는 작은 데코레이터를 작성하고 이를 몇 가지 다른 함수에 사용하세요.
자주 묻는 질문
*args와 **kwargs의 차이점은 무엇입니까?
*args는 추가 위치 인수를 튜플로 수집합니다. **kwargs는 사전에 추가 키워드 인수를 수집합니다. 함수는 두 가지를 함께 사용할 수 있습니다.
args와 kwargs라고 불러야 하나요?
아니요. 별이 작업을 수행하므로 *값 또는 **옵션이 동일하게 유효합니다. args와 kwargs는 단순히 널리 인정되는 규칙입니다.
*args와 **kwargs는 어떤 순서로 들어가야 하나요?
먼저 일반 매개변수, *args, 키워드 전용 매개변수, **kwargs가 마지막입니다. 다른 주문은 SyntaxError를 발생시킵니다.
함수 정의에서 단일 *는 무엇을 의미합니까?
*는 그 뒤의 모든 매개변수가 키워드로 전달되어야 함을 의미합니다. 특히 부울 플래그의 경우 호출이 더 명확해집니다.
Python 함수에서 /는 무엇을 의미하나요?
/ 앞의 매개변수는 위치 전용이므로 호출자는 이름으로 매개변수를 전달할 수 없습니다. 이 기능은 Python 3.8에 추가되었습니다.
계속 학습하세요
테스트, WordPress 또는 SEO에 도움이 필요하십니까?
우리는 팀이 더 나은 소프트웨어를 출시하고 사이트를 성장시킬 수 있도록 돕습니다. 현재 진행 중인 작업을 알려주시면 명확한 다음 단계를 제안해 드리겠습니다.
추가 가이드 테스트, AI 및 최신 개발
이 기사가 마음에 드셨나요? 주제를 선택하고 최신 튜토리얼로 바로 이동하세요.
AI 환각 설명: 언어 모델이 사물을 구성하는 이유와 이를 줄이는 방법
AI 환각은 그것이 무엇인지, 언어 모델이 환각을 생성하는 이유, 일반적인 유형, 접지 및 프롬프트를 통해 환각을 줄이는 방법, 그리고 우리가 실행한 간단한 점검에 대해 설명했습니다.
기사 읽기 →DevOps환경 변수 설명: .env 파일, 비밀 및 구성이 올바르게 완료되었습니다.
우리가 실행한 Python 예제를 통해 설명된 환경 변수: 읽기 및 설정, 모든 값이 문자열인 이유, .env 파일, 프로세스 상속, 비밀 및 유효성 검사.
기사 읽기 →소프트웨어 개발API 속도 제한 설명: 알고리즘, 헤더 및 429 오류 처리
우리가 실행한 시뮬레이션을 통해 설명된 API 속도 제한: 토큰 버킷, 고정 창, 슬라이딩 창, 429 응답, 속도 제한 헤더, 백오프를 사용한 재시도 및 테스트 제한.
기사 읽기 →테스트 자동화Python에서 조롱: unittest.mock, 패치 및 테스트를 거짓말로 만드는 실수
Unittest.mock을 사용하여 Python에서 모의, 테스트됨: 모의 및 return_value, 부작용, 이름이 사용되는 패치, 사양 및 자동 사양, 모의 날짜 및 일반적인 실수.
기사 읽기 →소프트웨어 테스트코드 커버리지 설명: 회선 커버리지와 분기 커버리지 및 100%의 실제 의미
실제 Coverage.py 실행을 통해 설명되는 코드 적용 범위: 라인, 분기 및 조건 적용 범위, 보고서 읽기, 100% 적용 범위가 여전히 버그를 놓칠 수 있는 이유 및 합리적인 대상.
기사 읽기 →데이터베이스 및 SQLSQL의 DELETE vs TRUNCATE vs DROP: 차이점, 롤백 및 사용 시기
테스트된 SQL을 통해 DELETE 대 TRUNCATE 대 DROP에 대해 설명합니다. 각각의 제거, 롤백, 트리거, ID 재설정, 속도 및 PostgreSQL, MySQL, SQL Server 및 SQLite의 차이점.
기사 읽기 →데이터베이스 및 SQLSQL 뷰 설명: 예제를 통해 함정 생성, 사용 및 방지
우리가 실행한 쿼리로 설명된 SQL 뷰: 뷰 생성, 실시간 결과, 열 숨기기, 성능, 업데이트 가능하고 구체화된 뷰, 손상된 종속성 및 모범 사례.
기사 읽기 →소프트웨어 개발TypeScript 인터페이스와 유형: 실제 차이점, 컴파일러로 테스트
TypeScript 인터페이스 대 유형, 실제 컴파일러로 확인: 둘 다 할 수 있는 것, 하나만 할 수 있는 것, 선언 병합, 확장 대 교차점 및 따라야 할 간단한 규칙.
기사 읽기 →소프트웨어 개발Python *args 및 **kwargs 설명: 명확한 예가 포함된 유연한 함수
Python *args 및 **kwargs는 우리가 실행한 코드(패킹 및 언패킹, 매개변수 순서, 키워드 전용 및 위치 전용 인수, 데코레이터 및 일반적인 오류)를 설명했습니다.
기사 읽기 →소프트웨어 개발Python Lambda 함수: 구문, 실제 사용 및 사용하지 말아야 할 경우
Python 람다 함수는 구문, 키를 사용한 정렬, 맵 및 필터, 클로저, 후기 바인딩 트랩, 일반 def가 더 나은 선택인 경우 등 우리가 실행한 코드로 설명되었습니다.
기사 읽기 →인공지능AI 에이전트란 무엇입니까? 작동 방식, 간단한 에이전트 루프를 사용하여 실행할 수 있음
AI 에이전트란 무엇입니까? 우리가 실행한 작은 Python 루프, 실제 위험 및 간단한 챗봇이 더 나은 선택일 때 에이전트 루프, 도구, 메모리 및 가드레일에 대한 일반 가이드입니다.
기사 읽기 →DevOps모니터링과 관찰 가능성: 로그, 지표, 추적을 통한 실제 차이점
모니터링과 관찰 가능성 설명: 알려진 오류와 알려지지 않은 오류, 로그, 지표 및 추적, 결제 사건 안내, 골든 신호, OpenTelemetry 및 유용한 경고.
기사 읽기 →DevOpsDocker 볼륨과 바인딩 마운트: 컨테이너 데이터를 올바른 방식으로 유지
Docker 볼륨과 바인드 마운트 설명: 컨테이너 데이터가 사라지는 이유, 명명된 볼륨, 바인드 마운트, tmpfs, Compose 예제, 백업, 권한 및 각 사용 시기.
기사 읽기 →테스트 자동화TDD와 BDD: 주요 차이점, 두 가지 방식으로 구축된 하나의 기능 및 각 사용 시기
TDD와 BDD는 두 가지 방식으로 구축된 하나의 할인 기능, 즉 우리가 실행한 코드를 사용한 적록 리팩토링, 주어진 시점 시나리오, 도구, 장단점 및 각 사용 시기를 설명합니다.
기사 읽기 →소프트웨어 개발Git merge vs rebase: 차이점, 예제, 언제 무엇을 쓸까
Git merge vs rebase를 실제 로그 출력, 비교표, rebase의 황금률, 안전한 팀 워크플로로 설명합니다.
기사 읽기 →소프트웨어 개발파이썬 리스트 컴프리헨션: 문법, 예제, 피해야 할 때
파이썬 리스트 컴프리헨션 설명: 문법, 필터링, if-else, 중첩 반복문, 실제 측정 시간, 그리고 일반 for 반복문이 더 나은 경우.
기사 읽기 →데이터베이스 및 SQL예제로 쉽게 배우는 SQL JOIN (Inner, Left, Right, Full)
샘플 테이블과 쿼리로 SQL JOIN을 단계별로 이해하세요. INNER, LEFT, RIGHT, FULL, CROSS, SELF와 흔한 실수, 성능 팁까지 정리했습니다.
기사 읽기 →