파이썬 공식 홈페이지 내 Data model 문서에 정의된 내용을 정리해본다.
1. 객체, 값 그리고 타입
객체란 파이썬의 데이터 추상화 방식이다. 모든 데이터는 객체, 혹은 객체들 사이의 관계로 정의된다.
(폰 노이만의 프로그램 내장방식 모델에 따라, 코드도 또한 객체로 표현될 수 있다.)
모든 객체는 본질을 갖는데, 그게 바로 값과 타입이다. 파이썬에서 한번 객체가 생성된 후, 이 값과 타입은 절대 바뀌지 않는다.
CPython 구현 디테일
CPython에서 id(x)는 x가 저장된 주소를 나타낸다.
파이썬에서 타입은 객체가 한번 정의된 후 바뀌지 않는데, 값을 바뀔 수 있다. 정확히는 바뀌는 값이 있고(mutable), 바뀌지 않는 값이 있다(immutable).
이러한 객체의 mutability는 타입에 따라 달라지는데, 대표적으로 인스턴스, 숫자, 스트링 그리고 튜플 같은 것들이 바뀌지 않는 값(immutable)이고, 딕셔너리, 리스트는 바뀌는 값(mutable)이다.
또한 파이썬에서 객체는 명시적으로 파괴되지 않고 재활용(Garbage collect)된다. 이말인즉슨, 파이썬에서 GC는 레퍼런스 카운팅을 통해 참조되지 않을 때 메모리에서 제거되는데, 이 내용은 추후에 자세히 다루어 보겠다.
이 것은 또한 외부 리소스에도 동일하게 적용되는데, close()로 명시적으로 해제되지 않는 경우 GC가 발생하기 전까지 해당 리소스는 메모리를 잡아먹는다. 그래서 공식 문서에서는 Try ... finally 문과 with 문을 통해 손쉽게 명시적으로 자원을 해제하기를 권장한다.
2. 표준 타입 계층구조
아래의 타입 구조들은 파이썬 내에 미리 정의된 것들이다. 추후 파이썬 버전에서 새로운 타입이 계층구조에 추가될 수 있다.
None 타입
None 타입은 단일 값을 나타낸다. 이 값에는 단일 객체가 붙는다. 이 객체는 None이라는 파이썬 내 빌트인 이름으로 불리워지는데, 프로그램 로직 내 값이 존재하지 않는 경우를 판단하기 위해 사용된다.
예를 들면, 명시적으로 아무 값도 반환하지 않는 함수의 리턴 타입으로부터 반환된다. 이 것의 실제값은 False이다.
numbers.Number
파이썬 내에 숫자 리터럴을 표현하고 산술연산을 빌트인으로 지원하기 위해 만들어진 타입이다.
- numbers.Integral
양/음의 정수를 표현하기 위한 Integer 타입의 집합이다. 정수를 표현하기 위한 Integer, 참/거짓을 표현하기 위한 Boolean이 존재한다. 비트 시프트 연산을 위해 이진표현이 가정되고, 음수는 좌측으로 확장되는 2의 보수로 표현되었다. - numbers.Real
기계레벨의 실수연산을 표현하기 위한 부동 소숫점 숫자 타입이다. 실수의 범위 및 오버플로우는 기계 아키텍처 표현에 따라 달라진다.
Sequence 타입
Sequence 타입은 유한한 숫자의 양수들로 인덱싱된 순서가 있는 집합이다. 파이썬 빌트인 함수 len()은 이들 시퀀스의 아이템들의 길이를 반환한다.
Sequence 타입도 또한 Immutable과 Mutable로 구분되어지는데, 이들의 차이는 선언되는 순간 메모리에 저장되어 변경될 수 있는지 여부이다.
- Immutable Sequences
1. String: 스트링 타입은 유니코드 코드 포인트를 일련의 시퀀스로 나타낸 값이다. 모든 스트링 값은 유니코드 U+0000에서 U+10FFFF 사이로 표현된다.
2. Tuples: 튜플 내 항목은 임의의 파이썬 객체이다. 튜플은 쉼표로 구분된 표현식에 두개 이상의 값을 구분하여 구성한다.
3. Bytes: 바이트 타입은 immutable한 배열이다. 뒤에서 설명하겠지만, mutable한 바이트 타입도 존재한다(Byte Arrays). - Mutable Sequences
1. Lists: 리스트 내 항목은 임의의 파이썬 객체이다. 리스트는 튜플과 같이 괄호쌍 사이에 쉼표로 구분된 표현식으로 구성되지만 값이 변경되어질 수 있다는 특성을 가진다.
2. Byte Arrays: 바이트 배열은 일반 바이트 타입과 달리 mutable한 배열이다. 이는 파이썬 빌트인 bytearrays() 생성자에 의해 만들어지며 immutable한 바이트 타입과 동일한 인터페이스를 제공한다.
Set 타입
Set 타입은 정렬되지 않으며, 유니크한 값들의 유한한, Immutable한 객체를 나타낸다.
- Set
일반적인 Set 타입은 mutable하다. 파이썬 빌트인 set() 생성자에 의해 만들어지며 add() 함수로 값이 추가되어진다. - Frozen Set
Frozen Set은 immutable한 Set 타입을 나타낸다. 이는 값이 변경되어질 수 없고, 동시에 hashable하다. 그래서 다른 집합 타입에서 재사용될 수 있고 또한 딕셔너리의 키 값으로 사용될 수도 있다.
Mapping 타입
Mapping 타입은 임의의 인덱스에 의해 표현되는 오브젝트들의 집합을 말한다. a[k]라는 표현식에서 매핑 a의 인덱스 k에 접근하는 값을 나타낼 수 있다.
- Dictionaries
딕셔너리는 파이썬에서 임의의 값으로 인덱싱된 유한한 객체들의 집합을 나타낸다. 딕셔너리에서 키나 값으로 들어올 수 없는 타입은 다른 mutable한 리스트나 집합이다. 이는 파이썬 내부 딕셔너리 타입의 구현과 연관이 있는데, 딕셔너리의 키는 해쉬되어질 수 있는 변하지 않는 상수값이어야 하기 때문이다.
딕셔너리는 또한 삽입된 순서를 유지한다. 이는 기존의 값이 변경되었을 때도 마찬가지인데, 예를 들어 a라는 키가 가리키는 값이 1인데 2로 변경했다고 하더라도 그 내부 메모리 상의 순서는 변경되지 않는다.
Module 타입
모듈은 import 시스템에 의해 만들어지고 import문에 의해 불리어지는 파이썬 코드의 기본 구성 유닛이다. 모듈 객체는 딕셔너리로 만들어진 네임스페이스를 가진다. 해당 모듈에 대한 속성의 lookup은 바로 이 딕셔너리를 통해 이루어진다. (e.g. m.x는 m.__dict__["x"]와 동일한 실행의미를 가진다.)