Python

[Python] Pickle - 객체 직렬화/역직렬화

비번변경 2024. 5. 28. 17:36

개요

2023.10.11-[Airflow] Dag 직렬화 (Serialization)에서 살펴보았는데, 직렬화(Serialization)란 데이터 구조나 객체 상태를 나중에 재구성할 수 있는 형식으로 변환하는 과정을 말한다. 다르게 말하면 객체를 바이트 스트림으로 인코딩하는 과정으로, 직렬화된 데이터는 동일하거나 다른 환경에 저장될 수 있다. 

반대로 직렬화된 데이터를 개체나 데이터 구조로 다시 재구성하는 과정, 또는 인코딩 되어있는 바이트 스트림으로부터 객체를 복원하는 과정을 역직렬화(Deserialization)라고 한다.

 

Python에서는 Pickle 라이브러리를 사용하여 데이터 직렬화/역직렬화를 수행한다. 이 글에서는 Pickle 라이브러리 사용법을 간단히 적어둔다.

 

 

Pickle

Pickle은 Python 객체나 데이터를 직렬화하거나 역직렬화할 때 사용할 수 있는 라이브러리다.

이때, 직렬화는 피클링(pickling), 마샬링(marshalling), 평탄화(flattening) 등의 단어로 말하기도 한다. 반대로 역직렬화는 역피클링(unpickling)이라고 말한다.

 

 

모듈 임포트

pickle 모듈을 사용할 때는 아래와 같이 import 하여 사용한다.

import pickle

 

 

직렬화 / 데이터 쓰기

객체를 직렬화할 때는 dump, dumps 함수를 사용한다.

 

dump 함수는 직렬화한 결과를 파일로 저장한다. 참고로 직렬화한 결과는 바이트 스트림이므로 파일로 작성할 때는 파일을 바이너리 모드('b')로 열어야 한다.

import pickle

data = {
    'a': [1, 2.0, 3, 4 + 6j],
    'b': ("character string", b"byte string"),
    'c': {None, True, False}
}

with open('peter.pickle', 'wb') as f:
    pickle.dump(data, f)

 

반면 dumps 함수는 직렬화한 결과를 bytes 객체로 반환한다.

import pickle

data = {
    'a': [1, 2.0, 3, 4 + 6j],
    'b': ("character string", b"byte string"),
    'c': {None, True, False}
}

dump_data = pickle.dumps(data)
print(f'type: {type(dump_data)}, \nvalue: {dump_data}')

 

 

역직렬화 / 데이터 읽기

문자열 데이터인 csv, json와 달리 직렬화한 데이터는 바이트 스트림이기 때문에 사람의 눈으로는 결과 데이터를 읽을 수 없다. 직렬화한 데이터를 다시 읽기 위해서는 역직렬화 과정이 필요하며 pickle 모듈에서는 load, loads 함수를 사용하여 수행할 수 있다.

load 함수는 바이너리 형식으로 저장된 파일을 읽어 역직렬화한다. dump 함수와 마찬가지로 파일을 읽을 때는 바이너리 모드로 읽어야 한다.

import pickle

data = {
    'a': [1, 2.0, 3, 4 + 6j],
    'b': ("character string", b"byte string"),
    'c': {None, True, False}
}

with open('peter.pickle', 'rb') as f:
    load_data = pickle.load(f)

print(load_data)

 

 

반면 loads 함수는 bytes 객체를 읽어 역직렬화한다. 역직렬화한 데이터가 Python 객체인 경우, 별도 처리 없이 바로 Python 객체로 사용할 수 있다.

import pickle

data = {
    'a': [1, 2.0, 3, 4 + 6j],
    'b': ("character string", b"byte string"),
    'c': {None, True, False}
}

dump_data = pickle.dumps(data)
load_data = pickle.loads(dump_data)
print(f'type: {type(load_data)}, \nvalue: {load_data}')

 

 

참고 문서

https://docs.python.org/ko/3/library/pickle.html#id1

https://wikidocs.net/8929

https://wikidocs.net/110788