티스토리 뷰

참조: https://wikidocs.net/18

변수란?

파이썬에서 사용하는 변수는 객체를 가리키는 것이라고도 말할 수 있다. 객체란 우리가 지금껏 보아 왔던 자료형을 포함해 "파이썬에서 사용되는 모든 것"을 뜻하는 말이다.
>>> a = 3
만약 위의 코드처럼 a = 3이라고 하면 3이라는 값을 가지는 정수 자료형(객체)이 자동으로 메모리에 생성된다. a는 변수의 이름이며, 3이라는 정수형 객체가 저장된 메모리 위치를 가리키게 된다. 즉, 변수 a는 객체가 저장된 메모리의 위치를 가리키는 레퍼런스(Reference)라고도 할 수 있다.
만약 메모리의 위치를 가리킨다는 말이 잘 이해되지 않는다면 다음처럼 생각해도 무방하다. 즉, a라는 변수는 3이라는 정수형 객체를 가리키고 있다.
a --> 3
[파이썬에서 "3"은 상수가 아닌 정수형 객체이다]
파이썬의 모든 자료형은 객체라고 했다. 그러므로 3은 우리가 일반적으로 생각하는 상수값이 아닌 하나의 "정수형 객체"이다. 따라서 a=3과 같이 선언하면 a.real처럼 내장 함수를 바로 사용할 수 있게 된다. C나 JAVA를 먼저 공부한 사람이라면 이 점이 헷갈릴 수 있다.
3의 자료형을 확인하는 아래 예제를 보면 좀 더 명확히 이해할 수 있을 것이다. type은 입력받은 객체의 자료형이 무엇인지 알려주는 함수이다.
>>> type(3)
<class 'int'>
다음 예를 보자.
>>> 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이 될 것이다.
[a, b, c는 정말 같은 객체를 가리키는 걸까?]
파이썬에는 입력한 자료형에 대한 참조 개수를 알려주는 sys.getrefcount라는 함수가 있다. 이 함수를 이용해 3이라는 정수형 객체에 참조 개수가 몇 개 있는지 살펴보자.
>>> import sys
>>> sys.getrefcount(3)
30
맨 처음 인터프리터를 실행한 후 sys.getrefcount(3)을 수행했을 때 참조 개수가 30이 나오는 이유는 파이썬 내부적으로 3이라는 자료형을 이미 사용했기 때문이다.
이후 a = 3, b = 3, c = 3과 같이 3을 가리키는 변수를 늘리면 참조 개수가 증가하는 것을 볼 수 있다.
>>> a = 3
>>> sys.getrefcount(3)
31
>>> b = 3
>>> sys.getrefcount(3)
32
>>> c = 3
>>> sys.getrefcount(3)
33


리스트를 변수에 넣고 복사하고자 할 때

여기서는 리스트 자료형에서 가장 혼동하기 쉬운 "복사"에 대해 설명하려고 한다. 다음 예를 통해 알아보자.

>>> 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가 가리키는 리스트와는 다른 리스트를 가리키게 하는 방법은 없을까? 다음의 2가지 방법이 있다.

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라는 처음 보는 형태가 나오는데, 이것은 뒤에 설명할 파이썬 모듈 부분에서 자세히 다룬다. 여기서는 단순히 copy라는 함수를 쓰기 위해서 사용되는 것이라고만 알아두자.

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

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

두 변수가 같은 값을 가지면서 다른 객체를 제대로 생성했는지 확인하려면 다음과 같이 is 함수를 이용하면 된다. 이 함수는 서로 동일한 객체인지 아닌지에 대한 판단을 하여 참과 거짓을 리턴한다.

>>> b is a
False

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


댓글
공지사항
최근에 올라온 글
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함