-
TIL.26 함수 매개변수 및 인수TIL 2020. 11. 3. 17:39728x90
# 함수에서 위치 인수와 키워드 인수 사용하기
## 위치 인수와 리스트 언패킹
## 위치 인수(positional argument) :
아래와 같이 함수에 인수를 순서대로 넣는 방식을 위치 인수라고 한다. 인수의 위치가 정해져있다는 뜻이다.
print(1, 2, 3)
# 우리가 사용하는 흔한 방식
## 위치 인수를 이용해 함수를 만들고 호출해보자.
def aaa (a, b, c): print(a) print(b) print(c) aaa(1, 2, 3) :: 1 2 3
## 언패킹 사용하기
## 위에서 만든 함수에서 언패킹을 사용해보자
## 아래와 같이 리스트 또는 튜플 앞에 *(애스터리스크)를 붙여 함수에 넣어주면 된다. (함수를 호출 할때)
# 함수(*리스트)
# 함수(*튜플)
def aaa (a, b, c): print(a) print(b) print(c) x = [10, 20, 30] # aaa(x) ## error # aaa([10, 20, 30]) ## error aaa(*x) aaa(*[10, 20, 30]) :: 10 20 30
# aaa(x) ## error
# aaa([10, 20, 30]) ## error## 이때 함수의 매개변수 개수와 리스트의 요소 개수가 같아야 한다. 다를 경우 함수를 호출 할 수 없다.
# TypeError: aaa() missing 2 required positional arguments: 'b' and 'c' //
2개의 매개변수가 더 필요하다는 내용의 에러가 뜸을 확인할 수 있다.
## 위치 인수와 리스트 언패킹 기능을 이용해 인수의 개수가 정해지지 않은 가변 인수에 사용 할 수 있다.
## 가변 인수 (variable argument) : 인수의 개수가 정해지지 않은, 인수의 개수를 제한하지 않는, 방식을 가변 인수라 한다.
## 가변 인수는 인수를 1개, 10개 또는 아무것도 넣지 않을 수 도 있다.
매개 변수 앞에 *(애스터리스크)를 사용하면 된다. (함수를 생성할때)
# def 함수이름(*매개변수):
# 코드
def bbb (*args): for arg in args: print(arg) bbb(10, 20, 30, 40, 50) :: 10 20 30 40 50 y = [10, 20, 30] bbb(y) :: [10, 20, 30] bbb(*y) :: 10 20 30 x = [10] bbb(x) :: [10] bbb(*x) :: 10
## 함수를 만들때 매개변수의 이름은 관례적으로 arguments 를 줄인 , "args"를 사용한다.
## 이 (args)는 튜플 형식으로 for 문으로 반복할 수 있다.
## 고정 인수와 가변 인수 함께 사용하기
def ccc (a, *args): print(a) print(args) ccc(1) :: 1 () # args에 인수를 입력하지 않았다. ccc (10, 100, 200, 300) :: 10 (100, 200, 300)
## 여기서 ccc(*args, a) 와 같이 가변인수는 고정 인수 보다 앞쪽에 위치하면 안된다.
## 반드시 매개변수 순서에서 *args는 가장 뒤쪽에 있어야 한다.
## 키워드 인수 사용하기
## 사용자의 개인정보를 출력해주는 함수를 예로 들어보자.
def personal_info(name, age, address): print('이름: ', name) print('나이: ', age) print('주소: ', address)
## 내가 만든 함수에서는 매개변수 1 ,2, 3이 무엇인지 알고 있어, 함수를 호출 할 경우 인수에 (이름, 나이, 주소)라는 인수를 넣어 함수를 호출하였지만
## 매번 함수 생성 당시 각각의 인수가 무슨 용도인지 직접 만든사람이 아니면, 알기가 어려웠다.
## personal_info(30, 홍길동, 서울)을 입력할 경우 이름은 30이 되고, 나이는 홍길동이 된다.
## 이러한 불편을 줄이기 위해 파이썬에서는 "키워드 인수"를 제공한다.
## 함수(키워드=값)
personal_info(name='홍길동', address='서울', age=30) :: 이름: 홍길동 나이: 30 주소: 서울
## 키워드 인수는 함수 호출 시 사용한다.
## 위 처럼 이름, 나이, 주소 의 순서가 아니여도 키워드 인수로 인해 해당하는 값이 정상적으로 들어가게 된다.
# 추가, 여지껏 키워드 인수는 많이 사용해온 것을 알 수 있다.
print(1, 2, 3, sep=':', end='') ## 매번 사용하던 sep, end 도 키워드 인수이다.
## 키워드 인수와 딕셔너리 언패킹 사용하기
## 딕셔너리를 사용한 키워드 인수 값 넣기
## 함수 호출 시 딕셔너리 앞에 ** (애스터리스크)2개를 붙혀주면 된다.
## 함수(**딕셔너리)
def personal_info(name, age, address): print('이름: ', name) print('나이: ', age) print('주소: ', address) x = {'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'} personal_info(**x) :: 이름: 홍길동 나이: 30 주소: 서울시 용산구 이촌동 personal_info(**{'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'}) :: 이름: 홍길동 나이: 30 주소: 서울시 용산구 이촌동
## 딕셔너리 변수 또는 딕셔너리 앞에 바로 **를 붙혀도 동작한다.
## 딕셔너리를 이용해 키워드 인수를 사용하기 위해선 몇가지 조건이 필요하다.
# 1. 딕셔너리 언패킹 사용시 함수의 매개변수 이름과 딕셔너리의 키 이름이 같아야 한다.
# 2. 매개변수의 개수와 딕셔너리 키의 개수도 같아야 한다, 이름 또는 개수가가 다르면 함수를 호출 할 수 없다.
# 3. 딕셔너리 키는 반드시 "문자열" 형태여야 한다.
## **(애스터리스크)를 2번 사용하는 이유
## 가장 큰 이유는 딕셔너리가 키 - 값 쌍의 형태로 값이 저장되어 있기 때문이다.
def personal_info(name, age, address): print('이름: ', name) print('나이: ', age) print('주소: ', address) x = {'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'} personal_info(*x) :: 이름::: name 나이: age 주소: address personal_info(**x) :: 이름: 홍길동 나이: 30 주소: 서울시 용산구 이촌동
## 애스터리스크를 1개만 사용할 경우 위와 같이 x의 "키" 값만 출력된다.
## 즉, 딕셔너리의 키 값만을 출력하고 싶다면 애스터리스크를 1번만 사용하면 된다.
(딕셔너리를 1번 언패킹하면 키가 사용된다는 뜻)
## 애스터리스크를 2번 사용하여 값을 사용하도록 만들어 준다.(딕셔너리 2번 언패킹하면 값이 사용된다는 뜻)
## 키워드 인수를 사용하는 가변 인수 함수 만들기
## 매개변수 앞에 ** 2개를 사용하면 된다.
# def 함수이름(**매개변수):
# 코드
def aaa (**kwargs): for kw, arg in kwargs.items(): print(kw, ':', arg)
## 매개 변수 이름은 관례적으로 keyword arguments를 줄여 kwargs를 사용한다.
## 특히 이 kwargus는 딕셔너리로 for 반복문으로 반복할 수 있다.
def aaa (**kwargs): for kw, arg in kwargs.items(): print(kw, ':', arg) aaa(name='홍길동') :: name : 홍길동 aaa(name='홍길동', age=30, address='서울시 용산구 이촌동') aaa(**x) :: name : 홍길동 age : 30 address : 서울시 용산구 이촌동
## 인수를 직접 넣어도 가능하며 딕셔너리 언패킹을 사용해도 된다.
## 인수와 딕서녀리 언패킹을 사용해도 값이 같음으로
# 딕셔너러 x ={'name': '홍길동'} 일때는 ->
add(**x) == add(name='홍길동')
# 딕셔너러 x ={'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'} 일때는 ->
add(**x) == add(name='홍길동', age=30, address='서울시 용산구 이촌동')으로 서로 같다는 걸 알 수 있다.
# 이처럼 함수를 만들 때 def personal_info(**kwargs):와 같이 매개변수에 **를 붙여주면 키워드 인수를 사용하는 가변 인수 함수를 만들 수 있다.
# 그리고 이런 함수를 호출할 때는 키워드와 인수를 각각 넣거나 딕셔너리 언패킹을 사용하면 된다.
## 보통 **kwargs를 사용한 가변 인수 함수는 아래와 같이 함수 안에 특정 키가 있는지 확인 뒤 해당 기능을 만든다.
def personal_info(**kwargs): if 'name' in kwargs: # in으로 딕셔너리 안에 특정 키가 있는지 확인 print('이름: ', kwargs['name']) if 'age' in kwargs: print('나이: ', kwargs['age']) if 'address' in kwargs: print('주소: ', kwargs['address'])
## 고정 인수와 가변인수(키워드 인수)를 함께 사용하기
def personal_info_1(name, **kwargs): print(name) print(kwargs) personal_info_1('홍길동') :: 홍길동 {} # 키워드 인수 아무것도 넣지 않음 personal_info_1('문타리', age=30, address='서울시 용산구 이촌동') :: 문타리 {'age': 30, 'address': '서울시 용산구 이촌동'}. personal_info_1(**{'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'}) :: 홍길동 # 앞에 문타리, 를 넣어줄 경우 고정인수 충돌 {'age': 30, 'address': '서울시 용산구 이촌동'}
## 위치 인수와 키워드 인수 함께 사용하기
def custom_print(*args, **kwargs): print(*args, **kwargs) custom_print(1, 2, 3, sep=':', end='') :: 1:2:3
## 이때 def custom_print(**kwargs, *args):처럼 **kwargs가 *args보다 앞쪽에 오면 안 된다.
## 매개변수 순서에서 **kwargs는 반드시 가장 뒤쪽에 와야 한다.
## 특히 고정 매개변수와 *args, **kwargs를 함께 사용한다면
## def custom_print(a, b, *args, **kwargs):처럼 매개변수는 고정 매개변수, *args, **kwargs 순으로 지정해야 한다.
## 매개변수에 초깃값 지정하기
## 함수를 호출 할때 항상 인수를 넣어 값을 전달하였다. 그렇다면 인수를 생략 할 수는 없을까?
## 이를 위해 함수를 정의할때 매개변수에 초깃값을 지정해주면 된다.
## 초깃값을 기본값으로 생각하여도 문제가 없을 것 같다.
왜냐하면 초깃값은 말그대로 초깃값으로 얼마든지 덮어씌워질 수 있기 때문이다.
def personal_info(name, age, address='비공개'): print('이름: ', name) print('나이: ', age) print('주소: ', address) personal_info('홍길동', 30) :: 이름: 홍길동 나이: 30 주소: 비공개 personal_info('홍길동', 30, '서울시 용산구 이촌동') :: 이름: 홍길동 나이: 30 주소: 서울시 용산구 이촌동
## 초기값이 지정된 매개변수의 위치
def personal_info(name, address='비공개', age): ## error print('이름: ', name) print('나이: ', age) print('주소: ', address)
## 매개변수에 초깃값을 지정해줄때는 순서 및 위치가 굉장히 중요하다.
## 위 코드에서 ('홍길동', 30)으로 호출 하였을때 30이 어디로 들어가야하는지 알 수 없기 때문이다.
## 즉, 초깃값이 지정된 매개변수는 아래와 같이 뒤쪽으로 몰아주면 된다.
def personal_info(name, age, address='비공개'): def personal_info(name, age=0, address='비공개'): def personal_info(name='비공개', age=0, address='비공개'):
# 참고// def personal_info(name='비공개', age=0, address='비공개'):와 같이
모든 매개변수에 초깃값을 지정하면 personal_info()처럼 인수를 넣지 않고 호출할 수 있다.
## 이처럼 함수 생성에서 사용되는 위치 인수, 키워드 인수에서는
### 리스트(튜플) 이면 ( + 위치인수) ==> * (에스터리스크 1개)
### 딕셔너리 이면 ( + 키워드인수)==> ** (에스터리스크 2개)를 사용한다는 점만 기억하자!
### *args <==> 호출 시 인수 개수가 다양한 경우 (생성시 매개변수)
### **kwargs <==> 키워드 인수로 호출이 이루어졌을 경우 (생성시 매개변수)
728x90'TIL' 카테고리의 다른 글
TIL. 28 람다 표현식(lambda) 사용하기 (0) 2020.11.05 TIL. 27 재귀 호출(recursive call) (0) 2020.11.04 TIL. 25 함수의 호출 과정 (0) 2020.11.02 TIL. 24 함수 만들고 사용하기 (0) 2020.11.01 TIL.23 N-gram 만들기 (0) 2020.10.31