Python 딕셔너리 파일로 저장: dict to pickle

현재 만들어진 딕셔너리 객체를 파일로 저장했다가 불러와야 하는 경우가 있습니다. 굳이 DB에 넣자니 번거롭고 간단히 파일에 저장하고 불러오면 될 때 사용하는 pickle을 이용해서 Python 딕셔너리 파일로 저장하는 방법 함께 살펴보겠습니다.

Python 딕셔너리 파일로 저장: pickle 사용법 개요

Python 자체에서 제공하는 방식으로 pickle이 있습니다. Pickle은 Python 객체를 직렬화(serialize)하고 역직렬화(deserialize)하는 데 사용되는 강력한 도구입니다. 직렬화는 Python 객체를 바이트 스트림으로 변환하여 파일에 저장하거나 네트워크를 통해 전송할 수 있게 하는 과정이고, 역직렬화는 그 반대 과정입니다.

객체 직렬화 및 파일로 저장

관례적으로 pickle을 이용해서 저장하는 파일의 확장자는 pkl을 이용합니다. open() 함수를 이용할 때 wb를 이용해서 쓰고, rb를 이용해서 불러옵니다. 여기에서 b는 바이너리 모드를 사용하겠다는 의미입니다.

아래의 코드를 통해서 딕셔너리 data를 data.pkl 파일로 저장해 보도록 하겠습니다.

import pickle

data = {"name": "강소영", "age": 30, "city": "구례군"}

# Pickle 파일로 저장
with open('data.pkl', 'wb') as file:
    pickle.dump(data, file)
Python

다음과 같이 data.pkl 파일로 정상적으로 저장된 것을 확인할 수 있습니다.

그림 1. Python 딕셔너리 파일로 저장한 결과: data.pkl
그림 1. Python 딕셔너리 파일로 저장한 결과: data.pkl

객체 역직렬화 및 파일로부터 읽기

이번에는 pickle로 직렬화하여 저장한 data.pkl을 읽어서 data_loaded로 불러온 후 내용을 확인해 보도록 하겠습니다.

import pickle

# Pickle 파일로부터 읽기
with open('data.pkl', 'rb') as file:
    data_loaded = pickle.load(file)
Python

data_loaded 값을 확인해 보면 라인 3에서 사용했던 값이 그대로 들어있는 것을 확인할 수 있습니다.

그림 2. data.pkl 역직렬화 해서 dictionary로 읽어오기
그림 2. data.pkl 역직렬화 해서 dictionary로 읽어오기

Pickle 사용 시 주의사항

pickle을 이용할 때 주의할 것이 2가지 있는데, 바로 보안 문제호환성 문제입니다.

보안 문제

Pickle은 신뢰할 수 없는 곳에서 가져온 pickle 데이터를 로드하지 말 것을 권고하고 있습니다. 왜냐하면 악의적인 데이터는 임의의 코드 실행을 유발해서 보안 문제가 발생할 수 있기 때문입니다. 그러므로 신뢰할 수 있는 pkl 파일에 대해서만 pickle.load()를 이용해서 로드하여 사용하기 바랍니다.

json과 같은 파일 포맷은 악성코드가 실행될 가능성이 없으므로 보안상 더 안전합니다. pkl 파일은 바이너리 스트림으로 저장되므로 어떤 내용이 들어있는지 cat 명령어를 사용해서 확인할 수가 없습니다.

호환성 문제

Pickle은 Python의 특정 버전에 종속적일 수 있으므로 다른 Python 버전 간의 호환성을 보장하지 않습니다. 따라서 장기적으로 데이터를 저장할 경우 csv나 json과 같은 다른 형식의 파일로 저장하는 것이 보다 안정적인 선택이 될 수 있습니다.

또한 Pickle은 python에서만 사용 가능하므로 다른 언어로 개발을 함께 하는 경우에는 해당 파일을 사용할 수가 없게 됩니다. 따라서 json과 같이 공용으로 사용 가능한 파일을 사용하는 것이 보다 바람직합니다.

Pickle의 유용한 옵션

프로토콜 버전 지정

Pickle은 여러 프로토콜 버전을 지원하고 있습니다. 프로토콜 버전이 높을수록 더 효율적인 직렬화가 가능합니다.

프로토콜 버전을 지정해서 pkl 파일을 저장할 수 있습니다. 다음과 같은 코드를 이용하면 가장 높은 버전의 프로토콜을 사용할 수 있습니다.

with open('data.pkl', 'wb') as file:
    pickle.dump(data, file, protocol=pickle.HIGHEST_PROTOCOL)
Python

pickle.DEFAULT_PROTOCOL도 있는데, Python의 버전에 따라 값이 다르므로 이전 버전과 호환되지 않습니다.

압축 사용하기

압축 옵션을 이용하면 pickle 파일을 저장할 때 저장 공간을 절약해서 사용할 수 있습니다.

import gzip

# 압축하여 저장
with gzip.open('data.pkl.gz', 'wb') as file:
    pickle.dump(data, file, protocol=pickle.HIGHEST_PROTOCOL)

# 압축된 파일 읽기
with gzip.open('data.pkl.gz', 'rb') as file:
    data_loaded = pickle.load(file)
Python

압축을 시도해 보았으나, pkl 파일보다도 용량이 크죠? pkl 파일이 너무 작기 때문에 압축 관련 오버헤드가 더 커서 파일이 큰 경우입니다. 딕셔너리의 크기가 더 크고 압축할 거리가 많다면 용량은 더 작아질 것입니다.

그림 3. gzip 활용하여 pickle 파일 압축해서 딕셔너리 파일로 저장한 결과
그림 3. gzip 활용하여 pickle 파일 압축해서 딕셔너리 파일로 저장한 결과

관련 자료

Python의 pickle을 참고하였습니다.

같이 읽으면 좋은 글

Leave a Comment