직렬화(Serialization)는 객체를 파일이나 메모리 버퍼에 저장할 수 있는 형태로 변환하는 과정입니다. 이렇게 변환된 데이터는 나중에 역직렬화(Deserialization)를 통해 원래의 객체로 다시 복원할 수 있습니다. 파이썬에서는 pickle 모듈을 사용해 이러한 작업을 손쉽게 처리할 수 있습니다.
피클링(Pickling)이란 무엇일까요?
파이썬의 pickle 모듈은 객체 구조를 직렬화하고 역직렬화하는 데 사용됩니다. 리스트(list), 딕셔너리(dict) 등 모든 종류의 파이썬 객체를 바이트 스트림(0과 1)으로 변환하는 과정을 피클링(pickling), 직렬화(serialization), 플래트닝(flattening), 마샬링(marshaling)이라고 부릅니다. 반대로 직렬화된 바이트 스트림을 다시 파이썬 객체로 되돌리는 과정은 언피클링(unpickling)이라고 합니다.
객체를 피클링하는 방법은 매우 간단합니다.
pickle모듈을 임포트한다dumps()함수를 호출한다
import pickle
class Vehicle:
def __init__(self, number_of_doors, color):
self.number_of_doors = number_of_doors
self.color = color
class Car(Vehicle):
def __init__(self, color):
Vehicle.__init__(self, 5, color)
Maruti = Car('Red')
print(str.format('My Vehicle Maruti is {0} and has {1} doors', Maruti.color, Maruti.number_of_doors))
pickle_Maruti = pickle.dumps(Maruti)
print('Here is my pickled Vehicle: ')
print(pickle_Maruti)
실행 결과
My Vehicle Maruti is Red and has 5 doors
Here is my pickled Vehicle:
b'\x80\x03c__main__\nCar\nq\x00)\x81q\x01}q\x02(X\x0f\x00\x00\x00number_of_doorsq\x03K\x05X\x05\x00\x00\x00colorq\x04X\x03\x00\x00\x00Redq\x05ub.'
위 예제에서는 Car 클래스의 인스턴스를 생성한 후 이를 피클링하여 자동차 인스턴스를 단순한 바이트 배열로 변환했습니다. 일단 객체가 피클링되면 바이너리 파일이나 데이터베이스 필드에 쉽게 저장할 수 있고, 나중에 필요할 때 이 바이트 묶음을 다시 객체 계층 구조로 복원할 수 있습니다.
참고: 피클링된 객체를 파일로 저장하려면 dumps() 대신 dump() 메서드를 사용해야 합니다.
언피클링(Unpickling)
언피클링은 피클링의 반대 연산으로, 바이너리 스트림을 받아서 객체 계층 구조로 변환하는 과정입니다.
언피클링은 pickle 모듈의 load() 함수를 사용하며, 바이트 스트림에서 완전한 객체 계층 구조를 그대로 반환받습니다.
import pickle
class Vehicle:
def __init__(self, number_of_doors, color):
self.number_of_doors = number_of_doors
self.color = color
class Car(Vehicle):
def __init__(self, color):
Vehicle.__init__(self, 5, color)
Maruti = Car('Red')
print(str.format('My Vehicle Maruti is {0} and has {1} doors', Maruti.color, Maruti.number_of_doors))
pickle_Maruti = pickle.dumps(Maruti)
# 이제 Maruti를 언피클링하여 새로운 인스턴스 Hyundai를 생성합니다.
Hyundai = pickle.loads(pickle_Maruti)
# 새 인스턴스에 다른 색상을 지정합니다.
Hyundai.color = 'Black'
print(str.format("Hyundai is {0}", Hyundai.color))
print(str.format("Maruti is {0}", Maruti.color))
실행 결과
My Vehicle Maruti is Red and has 5 doors
Hyundai is Black
Maruti is Red
위 예제를 보면 첫 번째 자동차 객체(Maruti)를 피클링한 후, 이를 다른 변수(Hyundai)로 언피클링했습니다. 즉, Maruti를 복제하여 Hyundai를 만든 것과 같습니다. 두 객체는 서로 독립적이므로 Hyundai의 색상을 변경해도 Maruti에는 영향을 주지 않습니다.
Pickle vs JSON 비교
JSON(JavaScript Object Notation)은 경량 데이터 교환 형식으로, 사람이 읽기 쉬운 것이 특징입니다. JSON이 pickle보다 갖는 큰 장점 중 하나는 표준화되어 있고 언어에 독립적이라는 점입니다. 또한 pickle보다 훨씬 안전하고 빠르다는 장점도 있습니다.
pickle의 대안으로는 cPickle도 있습니다. cPickle은 pickle과 거의 동일하게 동작하지만 C 언어로 작성되어 약 1000배 더 빠릅니다. pickle과 cPickle은 같은 파일을 공유해서 사용할 수 있습니다.
import json
mylist = [2, 4, 5, "ab", "cd", "ef"]
print("Here is my list: ", mylist)
json_string = json.dumps(mylist)
print("Here is my json encoded object: ", json_string)
print("Here is JSON back to a data structure: ", json.loads(json_string))
실행 결과
Here is my list: [2, 4, 5, 'ab', 'cd', 'ef']
Here is my json encoded object: [2, 4, 5, "ab", "cd", "ef"]
Here is JSON back to a data structure: [2, 4, 5, 'ab', 'cd', 'ef']
위 코드에서는 먼저 객체(리스트)를 만들고 dumps() 메서드를 사용해 문자열로 변환합니다. 그다음 loads() 메서드를 사용하면 해당 문자열을 다시 JSON 객체 데이터 구조로 되돌릴 수 있습니다.
정리하자면, 파이썬 내부적으로 객체를 저장·복원할 때는 pickle이 편리하고, 외부 시스템과 데이터를 주고받거나 사람이 읽을 수 있는 형식이 필요하다면 JSON을 선택하는 것이 좋습니다.