티스토리 뷰

Etc/Study

[Python] 함수와 매개변수

charming-l 2022. 2. 27. 03:51

빠르게 궁금증 해소하기! (클릭시 관련 부분으로 바로 이동합니다.)

** 궁금한 것들

❓ 매개변수의 변경으로 함수 밖의 변수 값이 변경될까?

❓ 전달받지 못한 함수 밖의 변수의 값을 가져올 수는 없을까?

❓ 입력값이 여러 개이고, 몇 개인지 구체적으로 셀 수는 없을 때 어떻게 하지?


함수

: ¹반복되는 연산을 한번에 정의함으로써 ²프로그램의 흐름을 일목요연하게 정리하기 위한 코드 뭉치

 

기본적인 형태는 다음과 같다.

이때, 입력값이나 출력값이 따로 필요하지 않다면 매개변수 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

 

 


참고

https://wikidocs.net/24

Comments