본문 바로가기
Python

[Python] pickle 모듈을 사용해서 직렬화, 역직렬화 하기

by teamnova 2023. 1. 8.

파이썬의 객체를 일련의 바이트들로 변환한 후 나중에 다시 파이썬 객체로 복원하게 할 수 있는데, 이렇게 파이썬 객체를 일련의 바이트들로 변환하는 것을 직렬화(Serialization)라 하고, 다시 바이트들을 파이썬 객체로 메모리 상에 복원하는 것을 역직렬화(Deserialization)이라 합니다.

 

직렬화 방식에는 Pickle, JSON, YAML 등 여러가지가 있습니다. Pickle 방식으로 직렬화를 하면 데이터가 바이너리 형식으로 저장되기 때문에 사람이 읽을 수 없는 반면, 저장이나 전송이 효율적입니다. 대신 JSON, YAML 방식은 저장이나 전송이 Pickle 보다는 덜 효율적이지만 사람이 읽을 수 있는 형태로 저장되기 때문에 가독성이 좋은 장점이 있습니다.

 

그리고 Pickle 방식으로 거의 모든 데이터 타입의 객체들을 직렬화할 수 있다는 것도 장점입니다. 다음은 Pickle로 직렬화 할 수 있는 데이터 타입의 종류입니다.

  • None, Boolean 값
  • 정수, 실수, 복소수
  • Sequence 데이터 타입 (리스트, 튜플, 스트링)
  • Collections (dictionaries, bytes, bytearrays)
  • 심지어 함수와 클래스까지도 직렬화할 수 있습니다.

반면에, 만약 JSON 방식으로 직렬화를 한다면 클래스와 함수는 직렬화할 수 없습니다. JSON 에서 지원하는 데이터 타입은 다음과 같습니다.

  • Strings
  • Numbers
  • JSON object
  • An Array
  • Boolean value
  • Null

 

참고로 Pickle 방식에서는 직렬화(serialization)는 Pickling 이라고도 하며, 역직렬화(deserialization)는 Unpickling 이라고도 합니다. 그리고 Pickle은 파이썬 종속적인 데이터 포맷으로, JSON은 거의 모든 프로그래밍 언어에서 지원(언어 독립적)되는 것에 반해 Pickling 은 Python에만 해당되며 언어 간 호환성을 보장하지 않습니다. 또한 서로 다른 파이썬 버전에서도 서로 호환되지 않습니다. 즉, Python 버전 2.x에서 수행된 피클링이 Python 버전 3.x에서 작동하지 않을 수 있음을 의미합니다.

 

 

 

이번 포스팅에서는 Pickle 모듈을 사용해서 직렬화를 해보도록 하겠습니다.

 

pickle 모듈을 아래와 같이 두 가지 다른 방식으로 사용할 수 있는데요,

 

1. pickle.dump(), pickle.load()

  • 파이썬 객체를 직렬화하여 이진 파일(binary file) 에 저장하고 - pickle.dump()
  • 직렬화되어 있는 이진 파일로 부터 파이썬 객체로 역직렬화하기 - pickle.load()

2. pickle.dumps(), pickle.loads()

  • 파이썬 객체를 직렬화하여 메모리에 저장하기 - pickle.dumps()
  • 직렬화되어 있는 바이트 객체를 파이썬 객체로 역직렬화하기 - pickle.loads()

 

이중에서 첫번째 방식인 파이썬 객체를 직렬화하여 바이너리 파일로 저장하는 방식을 사용하겠습니다.

그리고 python 3.9 버전을 사용했습니다.

 

 

import pickle

vege_dict = {'당근':34, '감자':66, '토마토':14, '브로콜리':28, '양파':34}

with open('pickled_dict.pickle', 'wb') as f:
	pickle.dump(vege_dict, f) # 직렬화

먼저 pickle 모듈을 임포트합니다. 그리고 야채의 칼로리 정보를 담고 있는 vege_dict 라는 딕셔너리 객체를 생성합니다. 그리고 현재 작업 폴더에 pickled_dict.pickle 이라는 파일을 생성하는데, 이 때 'wb'는 파일 열기 모드를 뜻하며 w는 쓰기모드, wb는 바이너리 파일 쓰기 모드를 뜻합니다. 그리고 pickle.dump를 하면 pickled_dict.pickle 파일에 직렬화된 vege_dict 딕셔너리 객체가 쓰여집니다.

 

 

with open('pickled_dict.pickle', 'rb') as f:
    loaded_dict = pickle.load(f) # 역직렬화
    
print(type(loaded_dict))
print(loaded_dict)

그 후에, pickle.load() 를 통해 역직렬화를 수행합니다. 역직렬화한 결과를 loaded_dict 라는 변수에 저장했는데, 해당 변수의 데이터 타입은 딕셔너리 타입이며 프린트해봤을 때 저장한 그대로 다시 역직렬화에 성공했음을 확인할 수 있습니다.