티스토리 뷰

6.6 레퍼런스값(=참조 값)에 의한 인자 전달(Passing Arguments by Reference Values)

*tip 레퍼런스값(=참조 값)의 개념이 헷갈린다면, c언어의 주소 값과 같다고 생각하면 이해하기 쉽다.

 

* 앞선 내용의 용어 복습

def 함수이름 (매개변수1, 매개변수2):

print("함수가 호출 되었습니다.")

 

함수이름(인자1, 인자2) # 함수를 인자와 함께 호출한다.

 

- 인자(arguments)를 이용해 함수를 호출 할 때, 각 인자의 레퍼런스(argument's reference)는 함수의 매개변수에 전됩니다.

- 파이썬의 모든 데이터는 사실 객체(object)이기 때문에, 한 객체를 가르키는 변수는 사실상 한 객체를 가르키는 레퍼런스(reference)이다.

- 인자(arguments)와 함께 함수를 호출 할 떄, 각 인자의 레퍼런스 값(reference value)은 함수의 매개변수로 전달 된다.

- 이를 값에 의한 전달(pass-by-value)라고 부른다.

- 요약하면, 함수를 호출 할 때 인자의 값(value of an argument)은 함수의 매개변수로 전달된다.

- 그 인자의 값 객체를 가르키는 레퍼런스 값이다.

 

- 만약 인자가 숫자(number) 문자(string)인 경우, 위의 내용들이 인자에 영향을 끼지치 않는다.

1
2
3
4
5
6
7
8
9
10
11
def main():
    x = 1
    print("Before the call, x is ",x)
    increment(x)
    print("After the call, x is",x)
 
def increment(n):
    n += 1
    print("\tn inside the function is ",n)
 
main()
cs

- 위의 코드를 보다시피, 변수 x(1)가 함수 increment의 매개변수 n에 전달과 동시에 호출이 되었다.

- 매개변수 n은 1 증가하였지만, 메인함수의 x는 함수 안에서 증가가 이루어졌음에도 아무런 변화가 없다.

- 이유는 x가 숫자(number)로 인자가 매개변수로 전달되었기 때문인데, 이것을 불변 객체(immutable objects)라고 부른다.

- 불변 객체(immutable objects)의 내용물은 바뀌지 않는다.

 

- 새로운 숫자를 변수에 할당할 때 마다, 파이썬은 그 새로운 숫자를 위한 객체를 새로 만들고, 새로 만든 객체의 레퍼런스(reference)를 숫자를 할당할 때 만든 변수에 할당한다.

 

*레퍼런스 예제

1
2
3
4
5
6
7
8
9
10
11
= 4
= x
print("y = x 일 때 레퍼런스:")
print(id(x))
print(id(y))
print()
 
= y + 1
print("y = y + 1 일 때 레퍼런스:")
print(id(x))
print(id(y))
cs

 

 

 

- line 2를 보면 변수 y에다 x를 할당하였다. 그러면 x와 y 둘 다 정수 4의 객체를 똑같이 가르키게 된다.

- 하지만 line 8에서와 같이 y에다 1을 더해주면 새로운 객체가 만들어지고 y에 할당되게 된다.

 

 

 



6.7 코드 모듈화하기(Modularizing Code)

 

- 모듈화는 코드의 유지보수(디버깅)를 용이하게 해주며, 코드를 재사용 할 수 있게 한다.

- 함수를 이용해 반복적인 코드와 코드의 재사용이 가능해지듯이, 함수를 모듈화(modularize)하여 좀 더 질 좋은 프로그램을 만들 수 있다.

- 파이썬에서는, 모듈(module)이라는 파일에다 함수정의를 저장 할 수 있다.

- 모듈의 확장명 .py 이며,  후에 모듈을 프로그램에 임포트(import)하여 재사용이 가능하다.

- 모듈 파일은 프로그램동일한 디렉토리에 배치해야 한다.

- 모듈은 하나 이상의 함수를 저장 할 수 있다.

- 같은 모듈 안에 존재하는 함수들서로 이름이 달라야 한다.

- turtle, random, math 들 역시 파이썬 라이브러리에 구현되어 있는 모듈이다.

 

- 최대공약수 프로그램을 GCDFunction.py 모듈에 함수를 저장하여 작성해보자.

 

*GCDFunction.py

1
2
3
4
5
6
7
8
9
10
def gcd(n1, n2):
    gcd = #최대공약수 1 초기화
    k = # 2부터 나눌 수 
 
    while k <= n1 and k <= n2:
        if n1 % k == and n2 % k == 0:
            gcd = k # 최대공약수 저장
        k += 1
 
        return gcd
cs

 

- 위와 같이 gcd 함수를 정의하여 GCDFunction.py로 저장한다.

- 다시 따로 프로그램(TestGCDFunction.py)을 작성하여 위에 작성한 gcd 함수를 사용할 수 있다.

 

*TestGCDFunction.py

1
2
3
4
5
6
7
from GCDFunction import gcd # gcd 함수 임포트
 
n1 = eval(input("Enter the first integer: "))
n2 = eval(input("Enter the second integer: "))
 
print("The greatest common divisor for ",n1 ,"and ", n2,
      " is ", gcd(n1,n2))
cs

 

- Line1를 보면 GCDFunction 모듈에서 gcd 함수를 임포트(import) 하였다.

- 이렇게 하면 프로그램과 함수는 서로 분리되어 저장되어 있지만, 본 프로그램에서 gcd함수를 사용 할 수 있게 된다.

- 그리고 아래와 같이 명령어를 작성하여 임포트(import) 할 수도 있다.

 

import GCDFunction

 

- 위와 같은 형식으로 임포트(import)하면 gcd 함수를 사용하기 위해선 GCDFuction.gcd 라고 작성하여 함수 호출을 하여야 한다.

- 이렇게 코드를 캡슐화(encapsulation) 얻을 수 있는 장점은 아래와 같다.

 

1. gcd를 계산하는 코드가 본 프로그램과 분리되어 있기 때문에, 로직이 깔끔해지고 코드를 읽기도 쉬워진다.

 

2. gcd 연산의 어떠한 오류든 gcd 함수 내로 국한되기 때문에, 디버깅의 범위를 줄일 수 있다.

 

3. 다른 프로그램에서도 gcd 함수를 사용 할 수 있다.

 

참고 문헌 : Introduction to Programming Using Python / Y.DANIEL LIANG



본 게시물은 개인적인 용도로 작성된 게시물입니다. 이후 포트폴리오로 사용될 정리 자료이니 불펌과 무단도용은 하지 말아주시고 개인 공부 목적으로만 이용해주시기 바랍니다.


교재 영어 원서를 직접 번역하여 정리한 게시물이므로 일부 오타, 의역이 존재할 수 있습니다. 틀린 부분이 있다면 댓글로 알려주시면 감사하겠습니다. 

 

 

댓글