파이썬 프로그램의 모든 데이터는 객체이거나 객체 간의 관계로 표현될 수 있다. 모든 객체는 아이덴티티(identity), 형(type), 값(value)을 갖는다. 또한, 변수를 할당하는 작업은 이러한 객체를 참조하는 형식으로 이루어진다.
>>> a = 12
>>> id(a)
2215190489744
>>> type(a)
<class 'int'>
>>> a
12
객체의 아이덴티티(identity)는 메모리상에서의 객체의 주소이며, 객체의 형(type)은 객체가 지원하는 연산들을 정의하고, 그 형의 객체들이 가질 수 있는 값들을 정의한다. 이 두 가지는 객체가 만들어진 후에는 변경되지 않는다.
객체의 값은 형에 따라 변경될 수도 있는데, 이 값이 변경되는가에 따라 객체를 크게 불변 객체(Immutable Object)와 가변 객체(Mutable Object)로 나뉠 수 있다.
클래스 | 불변 객체 |
---|---|
bool | o |
int | o |
float | o |
list | x |
tuple | o |
str | o |
set | x |
dict | x |
위의 분류에서 보면 숫자를 나타내는 int, float, 문자를 나타내는 str를 불변 객체라고 한다. 파이썬에서 변수를 할당하는 작업은 해당 객체에 대해 참조하는 것이다. 이 점을 유의하며 불변 객체가 무엇인지 아래의 예시를 통해 알아보자.
>>> 20
>>> a = 20
>>> b = a
>>> id(20), id(a), id(b)
(2215190490000, 2215190490000, 2215190490000)
id()
는 객체의 아이덴티티를 정수로 표현한 값을 return한다 (CPython 에서는 저장된 메모리 주소값을 돌려준다). 위의 예시는 각 변수를 생성하고, 변수들의 아이덴티티 값을 출력한 결과이다.
모든 변수가 같은 아이덴티티를 갖고 있다는 것을 알 수 있는데, 이는 a, b가 새롭게 생성된 원시 타입의 변수가 아니라 메모리에 선언된 20
이라는 객체를 참조했기 때문에 나오게 된 결과이다. 만약, 20
이 30
이 된다면, a와 b의 값도 바뀌겠지만 20
은 불변 객체인 int
형이기 때문에 변하지 않는다. a와 b를 30
을 할당 한다면 20
이 변하는 것이 아니라 int
형을 가진 새로운 30
이라는 객체가 생성되고 변수들은 이 객체를 참조하게 된다는 의미이다.
>>> a = 30
>>> b = a
>>> id(a), id(b), id(30), id(20)
(2215190490320, 2215190490320, 2215190490320, 2215190490000)
객체는 절대 명시적으로 파괴되지 않는다. 더 참조되지 않을 때 Garbage에 의해 Collect 된다.
is
와 ==
파이썬에서 사용하는 비교 연산자에는 is
와 ==
가 있다. 이 둘의 관계는 파이썬의 객체 구조와 관련이 잇는데, is
는 id()
값을 비교하는 함수이고, ==
는 값을 비교하는 함수이다.
>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> id(a), id(b)
(2215195866304, 2215196246400)
>>> a == b
True
>>> a is b
False
list
는 값이 바뀔 수 있는 객체인데, 이는 다른 변수가 list
를 참조하고 있을 때, list
의 값을 바꾸면 그 변수의 값 또한 변경된다는 이야기이다.
>>> a = [1, 2, 3, 4]
>>> b = a
>>> a[2] = 9
>>> a, b
([1, 2, 9, 4], [1, 2, 9, 4])
객체의 형은 거의 모든 측면에서 객체가 동작하는 방법에 영향을 준다. 객체의 identity에도 영향을 미친다. 불변 객체에서 새 값을 만들 때, 같은 형과 값을 가진 객체가 이미 존재하면 이 객체를 돌려줄 수도 있으나, 가변 객체에서 새 값을 만들 때는 절대 같은 형과 같은 값을 가진 객체가 있더라도 새로운 객체를 생성 한 후 이 값을 돌려준다.
다음은 3.2 표준형 계층, 콜러블
참조