오늘 배울 내용은 *args입니다.
1편에서 다룬 *과는 뭐가 다른것일까요?
*args는 쉽게 말해 함수에서 쓰는 *라고 보면 됩니다.
둘은 비슷하면서도 달라 매번 헷갈리는 녀석들인데요.
오늘 포스팅을 통해 두개가 무엇이 비슷하고 다른지 하나 하나 알아가보도록 합시다.
일반적인 형태에서 *사용과 함수에서 *사용의 비교
1)
먼저 복습차원에서 일반적인 * 사용을 보죠. 아래 코드의 결과가 무엇이 나올까요?
a, b, *c = 10, 20, 'a', 'c'
print(a)
print(b)
print(c)
output :
1편에서 배웠던 것 처럼 c는 a와 , b가 값을 받고 남은 값들을 리스트로 형태로 부여 받게 됩니다.
바로 이어 함수에서 쓰이는 *를 볼까요?
def func1(a, b, *c):
print(a)
print(b)
print(c)
func1(10,20,'a','c')
output :
뭔가 다른걸 발견하셨나요? ?
c가 리스트형태가 아닌 튜플입니다.
(참고로 함수에서 *를 쓸때는 *c가 아닌 *args형태로 씁니다. 이건 관습적인거라 실제 output에는 영향이 없습니다만, 지켜주는게 좋겠죠?
이 포스팅에서는 이해를 돕기위해 args를 쓰지 않을테니 참고바랍니다.)
2)
a, *b, c = 10, 20, 'a', 'c'
print(a)
print(b)
print(c)
이번에는 c가 아닌 가운데에 있는 b가 *를 가지고 있네요.
결과는 어떻게 나올까요?
output :
마찬가지로 a가 제일 첫번째 값 c가 나머지값 을 각 각 부여받고 남은 값들을 b가 리스트형태로 받았네요.
이어서 함수 형태를 볼까요?
def func1(a, *b, c):
print(a)
print(b)
print(c)
func1(10,20,'a','c')
지금까지 배운걸로 봤을때 아마 b는 20, 'a'를 튜플형태로 리턴하지 않을까 싶습니다.
output :
하지만 결과는 missing 1 required keword-only argument .. 라는 keyword-only argument가 필요하다는 에러를 리턴하네요..
(참고 : 함수안에 keyword argument는 func1(a=10, ..) 처럼 변수명에 어떤값을 넣을지 지정해서 함수를 부르는 형태를 말합니다. 그렇지 않고 위코드 처럼 적은 것이 positional argument 형태입니다.)
여기서 또 다른 점이 발견되네요!
positional argument를 이용할때 즉 위와 같이 사용할때는 *가 가운데 오면 안됩니다. 그럼 어디에 와야할까요?
제일 마지막에 와야 합니다.. 그렇기 때문에 함수를 정의할때 변수명에 *를 쓰실땐 위치를 조심해야 합니다.
"나는 그래도 *를 가운데 쓰고싶다"면 아래와 같이 positional argument를 지정해주시면 사용가능합니다.
def func1(a, *b, c):
print(a)
print(b)
print(c)
func1(10,20,'a',c = 'c')
output :
3)
이번에는 앞서 배운것과는 조금 다른 *를 사용법인데요.
지금까지는 함수를 정의할때 매개변수에 *를 붙혔다면 이번에는 함수를 실행할때 넣는 인자에 *를 붙히는 것입니다.
우선 일반적인 unapcking 예시부터 볼까요?
l = [10, 20, 30]
a, b , c = l
print(a)
print(b)
print(c)
l 이라는 리스트를 만들었고, l 을 a, b, c에 unpacking 을 하려고 합니다.
output :
우리가 1편에서 배웠듯이 iterable 중 하나인 리스트의 원소값들을 자동으로 그 위치에 맞게 값을 할당합니다.
같은 방법으로 함수에도 적용해볼까요?
l = [10, 20, 30]
def func1(a, b, c):
print(a)
print(b)
print(c)
func1(l)
output :
missing required positinal arguments 라는TypeError가 발생하네요.
에러를 읽어보면 b 와 c에는 값을 부여받지 못했다는 말이네요 ,즉 a자리에만 리스트 하나가 통째로 들어갔네요.
함수에서는 알아서 리스트원소들을 unpacking을 안해준다는걸 알게되었습니다.
그러면 어떻게 해야 리스트를 함수에 넣을 수있을까요?
바로 함수를 실행할때 넣는 인자에 *를 추가해줍니다.
1편에서도 확인했지만
*를 iterable 형태의 데이터 앞에 붙혀주면 , 아래 코드처럼 각 원소를 unpacking해주는 역할을 합니다.
l = [10, 20, 30]
print(*l)
output :
unpacking이 완료된 값들을 func1 인수값으로 넣어주면 아래와 같이 우리가 원하는 값을 가질 수있습니다.
def func1(a, b, c):
print(a)
print(b)
print(c)
func1(*l)
output :
정리
함수를 정의할때 매개변수에 *를 붙히는것과 함수 인수로 사용하기 위해 unpacking할때 쓰는 *를 잘 구별하셔야 합니다.
헷갈릴때마다 다시 한번 연습하셔서 완전히 자기것으로 만드시길 바래요:)
이글과 읽으면 좋은글
'파이썬 > 파이썬 중급' 카테고리의 다른 글
[파이썬 중급] @property, @함수명.setter 사용법 (1) | 2021.07.23 |
---|---|
[파이썬 중급] 진법 변환(N진수 -> 10진수 | 10진수 -> N진수) (0) | 2021.06.18 |
[파이썬 중급] map, filter | zip + list comprehension (0) | 2021.05.18 |
[파이썬 중급] unpacking에 대해서 잘 알고 계시나요?(*, ** 사용법) (3) | 2021.04.22 |
[파이썬 중급] 클래스(CLASS) body 스코프(scope) 개념 정리! (0) | 2021.04.16 |
댓글