10) 변수

우리는 이미 변수들을 사용해 왔다. 다음 예와 같은 a, b, c를 파이썬 변수라고 한다.

 

>>> a = 1 
>>> b = "python"
>>> c = [1,2,3]

 

변수를 만들 때는 위의 예에서와 같이 '='(assignment) 기호를 사용한다.

앞으로 설명할 부분은 프로그래밍 초보자가 얼른 이해하기 어려운 부분이므로 당장 이해가 되지 않는다면 그냥 건너뛰어도 무방하다.

파이썬에 대해서 공부하다 보면 자연스럽게 알 게 될 것이다.

 

변수란

 

변수는 객체를 가리키는 것이다. 객체란 우리가 지금껏 보아왔던 자료형을 포함한 파이썬에서 사용되는 그 모든 것을 뜻하는 말이다.

 

>>> a = 3

 

만약 위의 코드처럼 a = 3 이라고 했다면 3이라는 값을 가지는 정수 자료형(객체)이 자동으로 메모리에 생성된다.

a는 변수 이름으로서 3이라는 정수형 객체가 저장된 메모리 위치를 가리키게 된다. 즉, a는 레퍼런스(Reference)이다.

이해가 잘 되지 않는다면 이렇게 생각해보자.

 

a --> 3

 

즉, a라는 변수는 3이라는 정수형 객체를 가리키고 있다.

다음 예를 보자.

 

>>> a = 3
>>> b = 3
>>> a is b
True

 

a가 3을 가리키고 b도 3을 가리킨다.

즉 a = 3을 입력하는 순간 3이라는 정수형 객체가 생성되고 변수 a는 3이란 객체의 메모리 번지를 가리킨다.

다음에 변수 b가 동일한 객체인 3을 가리킨다.

즉 3이라는 정수형 객체를 가리키고 있는 변수는 2개가 된다.

이 두 변수는 가리키고 있는 대상이 동일하다.

따라서 동일한 객체를 가리키고 있는지 아닌지에 대해서 판단하는 파이썬 내장함수인 is 함수를 a is b처럼 실행했을 때 참(True)을 리턴하게 된다.

3이라는 객체를 가리키고 있는 변수의 개수는 2개이다.

이것을 조금 어려운 말로 레퍼런스 카운트(Reference Count, 참조갯수)가 2개라고 한다.

만약 c = 3이라고 한번 더 입력한다면 레퍼런스 카운트는 3이 될 것이다.

 

변수 없애기

 

3이라는 정수형 객체가 메모리에 생성된다고 했다.

그렇다면 이 값을 메모리에서 없앨 수 있을까?

3이라는 객체를 가리키는 변수들의 개수를 레퍼런스 카운트라 하였는데, 이 레퍼런스 카운트가 0이 되는 순간 3이라는 객체는 자동으로 사라진다.

즉 3이라는 객체를 가리키고 있는 것이 하나도 없을 때 이 3이라는 객체는 메모리에서 사라지게 되는 것이다.

이것을 또한 어려운 말로 쓰레기 수집 - 가비지 콜렉션(Garbage collection)이라고도 한다.

다음의 예는 특정한 객체를 가리키는 변수를 없애는 예를 보여준다.

 

>>> a = 3 
>>> b = 3
>>> del(a)
>>> del(b)

 

위의 예를 살펴보면 a와 b가 3이란 객체를 가리켰다가 del이란 파이썬 내장함수에 의해서 가리키는 변수 a, b가 사라지게 되고 따라서 레퍼런스 카운트가 0이 되어서 객체 3도 메모리에서 사라지게 된다.

 

※ 사용한 변수를 del 명령어를 이용하여 일일이 삭제할 필요는 없다. 파이썬이 이 모든것을 자동으로 해 주고 있기 때문이다. (가비지 콜렉션)

 

변수를 만드는 여러 가지 방법

 

방법 1)

>>> a, b = 'python', 'life'

 

방법 1처럼 터플로 a, b에 값을 대입할 수 있다. 이 방법은 아래 소개된 방법 2와 완전히 동일하다.

 

방법 2)

>>> (a, b) = ('python', 'life')

 

방법 1과 방법 2는 사실상 같다. 터플 부분에서도 언급했지만 터플은 괄호를 생략해도 된다.

 

방법 3)

>>> [a,b] = ['python', 'life']

 

방법 3처럼 리스트로 만들 수도 있다.

 

방법 4)

 

>>> a = b = 'python'

 

여러 개의 변수에 같은 값을 대입할 수도 있다.

위의 방법을 이용하여 파이썬에서는 두 변수 값을 바꾸는 매우 간단하고 쉬운 방법을 쓸 수 있다.

 

>>> a = 3
>>> b = 5
>>> a, b = b, a 
>>> a
5 
>>> b
3

 

처음에 a 에는 3, b에는 5라는 값이 대입되어 있었지만 a, b = b, a라는 문장을 수행한 뒤 그 값이 서로 바뀌었음을 확인 할 수 있다.

 

리스트 복사

 

여기서는 리스트라는 자료형에서 가장 혼동하기 쉬운 부분을 설명하려고 한다. 예를 보며 알아보도록 하자.

 

>>> a = [1,2,3]
>>> b = a
>>> a[1] = 4
>>> a 
[1, 4, 3]
>>> b
[1, 4, 3]

 

위의 예를 유심히 살펴보면 b라는 변수에 a가 가리키는 리스트를 대입하였다.

그런 다음, a 리스트의 a[1]을 4라는 값으로 바꾸었을 때, a리스트만이 바뀌는 것이 아니라 b리스트도 똑같이 바뀌게 된다.

그 이유는 a, b 모두 같은 리스트인 [1, 2, 3]을 가리키고 있었기 때문이다.

a, b는 이름만 다를 뿐이지 완전히 동일한 리스트를 가리키고 있는 변수이다.

그렇다면 b 변수를 생성할 때 a와 같은 값을 가지면서 a 가 가리키는 리스트와는 다른 리스트를 가리키게 하는 방법은 없을까?

다음의 두 가지 방법이 있다.

 

방법 1) [:] 이용

 

첫 번째 방법으로는 아래와 같이 리스트 전체를 가리키는 [:]을 이용하는 것이다.

 

>>> a = [1, 2, 3] 
>>> b = a[:]
>>> a[1] = 4
>>> a
[1, 4, 3]
>>> b
[1, 2, 3]

 

위의 예에서 보듯이 a 리스트 값을 변형하더라도 b리스트에는 영향을 끼치지 않음을 볼수 있다.

 

방법 2) copy 모듈 이용

 

두 번째 방법은 copy 모듈을 이용하는 방법이다.

다음의 예제에서 보면 from copy import copy라는 처음 보는 형태가 나오는데 이것은 2장의 모듈 부분에서 자세히 다루게 된다.

여기서는 단순히 copy라는 함수를 쓰기 위해서 사용되는 것이라고만 알아두자.

 

>>> from copy import copy 
>>> b = copy(a)

 

위의 예 b = copy(a) 는 b = a[:]과 동일하다.

 

두 변수가 같은 값을 가지면서 다른 객체를 제대로 생성했는 지를 확인하려면 다음과 같이 하면 된다.

즉, is 함수를 이용한다.

이 함수는 서로 동일한 객체인지 아닌지에 대한 판단을 하여 참과 거짓을 돌려준다.

 

>>> b is a
False

 

위의 예에서 b is a 가 False를 돌려주므로 b와 a 가 다른 객체임을 알 수 있다.

 

예제를 연습해 봅시다