본문 바로가기
Python

[Py] Serialization of Python: pickle

by ds31x 2024. 11. 27.

1. Python의 pickle 모듈

  • Python의 pickle 모듈은 Python 객체를 직렬화(serialize)하여 파일 또는 메모리에 저장.
  • 저장된 데이터를 다시 역직렬화(deserialize)하여 원래 객체로 복원.
  • 데이터를 영구 저장하거나 네트워크를 통해 전송할 때 유용.

Serialization은
데이터를 저장하거나 전송할 수 있도록
object를 연속적인 bytes 형태로 변환 하는 과정

 

 

Pickle과 비슷한 것으로 Marshal이 있으나,
이는 목적이 Python 내부적으로 객체를 바이트 스트림으로 직렬화하거나 이를 역직렬화하여 다시 Python 객체로 복원하는 것으로 주로 Python의 .pyc 파일 생성과 같은 내부적인 작업에 사용됨.
버전에 따른 호환성 등이 매우 부족하므로 용도가 다름.

2. 주의 사항

  1. 보안 문제 (Security Risks):
    • pickle은 신뢰할 수 없는 소스에서 데이터를 로드하면 보안 위험 존재.
    • 악의적인 코드가 포함된 데이터를 실행할 가능성이 있음.
    • 반드시 신뢰할 수 있는 데이터만 로드.
  2. 호환성 문제 (Compatibility Issues):
    • Python 2.x와 3.x 간 pickle 데이터가 호환되지 않을 수 있음.
    • 호환성을 유지하려면 protocol=2를 명시적으로 설정.

3. pickle 기본 사용법

3-1. 객체 저장 (쓰기): dump

  • Python 객체를 .pkl 파일로 저장하려면 pickle.dump()를 사용.
  • 바이너리 쓰기 모드('wb')로 파일 열기.
import pickle

data = {"name": "Alice", "age": 25, "scores": [95, 88, 92]}

with open("data.pkl", "wb") as file:
    pickle.dump(data, file)
print("객체가 저장되었습니다.")

3-2. 객체 읽기: load

  • 저장된 .pkl 파일을 다시 Python 객체로 복원하려면 pickle.load()를 사용.
  • 바이너리 읽기 모드('rb')로 파일 열기.
import pickle

with open("data.pkl", "rb") as file:
    loaded_data = pickle.load(file)

print("저장된 객체를 읽어왔습니다.")
print(loaded_data)

 


3-3. 전체 흐름 예제

  1. 객체 생성:
    • Python 객체를 생성.
  2. 객체 저장:
    • pickle.dump().pkl 파일에 저장.
  3. 객체 읽기:
    • pickle.load().pkl 파일에서 데이터 복원.
import pickle

# 1. 객체 생성
example_object = {
    "id": 123,
    "name": "John Doe",
    "attributes": ["smart", "kind", "friendly"],
    "scores": {"math": 90, "science": 88},
}

# 2. 객체 저장
with open("example.pkl", "wb") as file:
    pickle.dump(example_object, file)

# 3. 객체 읽기
with open("example.pkl", "rb") as file:
    loaded_object = pickle.load(file)

print("저장된 객체:")
print(loaded_object)

 


4. 참고: 직렬화 프로토콜 (Serialization Protocol)

  • pickle은 데이터를 직렬화할 때 다양한 프로토콜(protocol) 버전을 지원.
  • 각 프로토콜은 효율성과 호환성에 영향을 미침.

4-1.프로토콜 종류

  1. 프로토콜 0 (protocol=0)
    • 텍스트 기반 직렬화.
    • Python 2.x와 호환성 제공.
    • 현대 환경에서는 비효율적이며 거의 사용되지 않음.
  2. 프로토콜 1 (protocol=1)
    • 초기 바이너리 포맷.
    • Python 2.x와 호환성 제공.
  3. 프로토콜 2 (protocol=2)
    • Python 2.3 이상에서 사용 가능.
    • new-style 클래스와 같은 새로운 객체 유형 지원.
    • Python 2.x와 3.x 간 호환성을 유지하려면 사용.
  4. 프로토콜 3 (protocol=3)
    • Python 3 전용.
    • UTF-8 문자열 데이터를 효율적으로 처리.
    • Python 3.x 환경에서 기본으로 사용됨.
  5. 프로토콜 4 (protocol=4)
    • Python 3.4 이상에서 사용 가능.
    • 대규모 객체 및 재귀적 데이터 구조 지원.
    • 최대 4GB 이상의 데이터 직렬화 가능.
  6. 프로토콜 5 (protocol=5)
    • Python 3.8 이상에서 사용 가능.
    • Out-of-band data(메모리 외부 데이터를 처리)를 지원.
    • 최신 Python 환경에서 가장 효율적이며 추천.

4-2. 프로토콜 지정 예제

최신 프로토콜 자동 선택 (기본값 사용):

with open("data.pkl", "wb") as file: 
    pickle.dump(data, file)

특정 프로토콜 강제 지정:

with open("data.pkl", "wb") as file: 
    pickle.dump(data, file, protocol=2) # Python 2.x와 호환

최신 프로토콜 강제 사용:

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

5. 참고: 메모리 기반 직렬화 (Memory-based Serialization)

  • 파일 대신 메모리에 데이터를 저장 및 복원 가능.
  • io.BytesIO를 활용.

5-1. 예제

import pickle
import io

data = {"key": "value", "number": 42}

# 메모리 기반 객체 직렬화
buffer = io.BytesIO()
pickle.dump(data, buffer)

# 객체 읽기
buffer.seek(0)  # 버퍼의 처음으로 이동
loaded_data = pickle.load(buffer)
print(loaded_data)

6. picklejoblib 비교

  1. pickle:
    • 모든 Python 객체를 직렬화 가능.
    • 범용 도구로 객체 전송 및 영구 저장에 적합.
  2. joblib:
    • 대규모 배열(Numpy)수치 데이터 직렬화에 최적화.
    • 직렬화 속도가 빠르고, 저장된 파일 크기가 작음.

7. 결론

  • Python 객체 저장: pickle.dump().
  • 저장된 객체 읽기: pickle.load().
  • 최신 프로토콜 사용: pickle.HIGHEST_PROTOCOL 권장.
  • 데이터 호환성: 필요 시 protocol=2 사용.
  • 보안 문제에 유의하고 신뢰할 수 있는 데이터만 로드.

관련자료

2023.12.05 - [Python] - [Python] File Handling

 

[Python] File Handling

File 열고 닫기.2023.07.04 - [Python] - [Python] file : open and close [Python] file : open and closePython 에서 file을 처리하기 위해선 다른 프로그래밍 언어와 마찬가지로 file에 대한 접근이 가능한 object를 얻어와야

ds31x.tistory.com