티스토리 뷰
빠르게 궁금증 해소하기! (클릭시 관련 부분으로 바로 이동합니다.)
** 궁금한 것들
❓ 매개변수의 변경으로 함수 밖의 변수 값이 변경될까?
❓ 전달받지 못한 함수 밖의 변수의 값을 가져올 수는 없을까?
❓ 입력값이 여러 개이고, 몇 개인지 구체적으로 셀 수는 없을 때 어떻게 하지?
함수
: ¹반복되는 연산을 한번에 정의함으로써 ²프로그램의 흐름을 일목요연하게 정리하기 위한 코드 뭉치
기본적인 형태는 다음과 같다.
이때, 입력값이나 출력값이 따로 필요하지 않다면 매개변수와 return는 생략할 수 있다.
def 함수명(매개변수):
<수행할 문장1>
<수행할 문장2>
...
return
매개변수
: 매개변수란 함수의 입력으로, 외부로부터의 전달받은 값을 저장한 변수
매개변수와 인자
❗ 인자란 함수의 입력값으로 전달되는 값 자체를 의미한다. 매개변수와 혼동하지 않도록 한다.
>>> def sub(a, b): # a, b는 매개변수
∙∙∙ return a-b
∙∙∙
>>> result = sub(7, 3) # 7, 3은 인자
초깃값 설정
매개변수에 입력값이 들어오지 않았을 때를 대비해 초깃값을 미리 설정해둘 수도 있다.
단, 초깃값이 설정된 매개변수는 반드시 맨 뒤에 위치해야한다.
# 올바른 초깃값 설정
>>> def sub(a, b=2):
∙∙∙ print(a-b)
∙∙∙
>>> sub(3) # a=3, b=2(초깃값)
1
# 잘못된 초깃값 설정
>>> def sub(a=5, b):
∙∙∙ print(a-b) # Syntax Error 발생
궁금증 해결하기
❓ 매개변수의 변경으로 함수 밖의 변수 값이 변경될까?
정답은 "반은 맞고 반은 틀리다"라고 할 수 있겠다.
인자와 인자의 값을 저장한 매개변수는 초기에 같은 레퍼런스를 갖지만, 매개변수의 값을 변경시키면 매개변수에 레퍼런스를 새로이 할당한다. 즉, 매개변수의 값 변경 이후에는 인자와 매개변수는 별도의 변수로, 서로 어떠한 영향도 줄 수 없다는 것이다.
그런데 왜 반은 맞다고 하였는가에 대해 말해보자면, list나 dictionary와 같은 배열이 매개변수로 할당될 경우, 함수 내에서 배열의 원소 추가/삭제에 관해서는 서로 영향을 준다. 한 바구니에 쿠키가 담겨있는데, 그 바구니에 쿠키를 하나 더한다고 바구니가 바뀌는 것인가? 당연히 아니다. 배열을 바구니로, 그 안의 원소들을 쿠키라고 생각을 하면 된다. 레퍼런스는 내용물과는 상관없이 배열(바구니)에 고유값을 매긴 것으로, 매개변수의 배열에 원소(쿠키)가 추가된다고 해서 레퍼런스가 바뀌지는 않는다는 소리다. 이 연산에 있어서는 매개변수와 인자의 레퍼런스는 동일하기 때문에 서로 영향을 줄 수 있다.
python에서는 id() 를 통해서 객체의 레퍼런스(고유값)를 출력할 수 있는데, 이를 통해서 알아보자.
- 인자와 매개변수는 초기에 값은 레퍼런스를 가진다.
>>> def func(a):
∙∙∙ print(a, id(a))
∙∙∙
>>> b = 3
>>> func(b)
>>> print(b, id(b))
3 9788672 # a = 3, a의 레퍼런스
3 9788672 # b = 3, b의 레퍼런스
- 매개변수의 값을 바꾸는 순간 인자와 레퍼런스가 달라진다.
>>> def func(a):
∙∙∙ a = 2
∙∙∙ print(id(a))
∙∙∙
>>> b = 3
>>> func(b)
>>> print(b, id(b))
2 9788640 # a = 2, a의 레퍼런스
3 9788672 # b = 3(값이 변경되지 않음), b의 레퍼런스
- 배열이 매개변수로 들어올 경우 원소의 삽입/삭제 연산은 인자에 영향을 준다.
>>> def func(a):
∙∙∙ a.append(4)
∙∙∙ print(id(a))
∙∙∙
>>> b = [1, 2, 3]
>>> func(b)
>>> print(b, id(b))
[1, 2, 3, 4] 140067534058816 # a = [1, 2, 3, 4], a의 레퍼런스
[1, 2, 3, 4] 140067534058816 # b = [1, 2, 3, 4](값이 변경됨), b의 레퍼런스
❓ 전달받지 못한 함수 밖의 변수의 값을 가져올 수는 없을까?
가져올 수 있다. 함수 밖의 변수의 이름 앞에 global을 붙여 선언 후 사용하면 된다. 하지만 외부에 종속적인 함수는 효율적이지 못하므로, return을 사용해 외부의 변수의 값을 재할당하도록 하는 방법을 권장한다.
- 함수 내부에서 global 선언 (권장 X)
>>> def sub():
∙∙∙ global a
∙∙∙ a = a-1
∙∙∙
>>> a = 2
>>> sub()
>>> print(a)
1 # 함수 적용후 a의 값이 바뀜
- return을 활용하여 외부 변수 값 재할당 (권장 O)
>>> def sub(b):
∙∙∙ b = b-1
∙∙∙ return b
∙∙∙
>>> a = 2
>>> a = sub(a)
>>> print(a)
1 # 함수 적용후 a의 값이 바뀜
❓ 입력값이 여러 개이고, 몇 개인지 구체적으로 셀 수는 없을 때 어떻게 하지?
매개변수의 이름 앞에 *을 붙여 넘겨받으면 된다.
>>> def add(*args):
∙∙∙ result = 0
∙∙∙ for i in args:
∙∙∙ result += i
∙∙∙ print(result)
∙∙∙
>>> add(1, 3, 5)
9
>>> add(2, 4, 6, 8, 10)
30