파이썬에서 직렬화 혹은 역직렬화를 진행하려고 할 때 자주 사용되는 모듈이 있다.
json
과 pickle
이다. 이번 포스트에서는 이 둘의 차이에 대해서 설명하고 각각의 모듈이 가진 method의 활용법에 대해서 정리하려고 한다.
사실 json 은 파이썬에서 직렬화, 역직렬화를 제공하는 모듈이라고 보기는 어려운거 같다. 직렬화란 파이썬 객체를 바이트형태로된 직렬화된 데이터로 바꿔주는 것을 의미하는데 json 은 byte 형태로 변환하는 것이 아니고 str 형태로 변환하게 된다. 이 부분이 바로 pickle 모듈과의 차이라고 할 수 있다.
반대로 직렬화된 바이트 데이터를 다시 파이썬 객체로 복구시키는 것을 역직렬화라고 한다.
정리하자면 json은 str 객체로 만들어주는 직렬화, 역직렬화 방식이고 pickle 은 바이트 형태로 만들어주는 직렬화, 역직렬화다.
json 모듈에서는 dump, dumps, load, loads 이렇게 4가지 매소드가 주로 사용되는데 각각에 대해서 알아보자
dump계열은 객체를 직렬화하는 역할을 한다. dump, dumps의 차이는 스트림에 전달을 하느냐 아니냐의 차이다. dump는 stream을 통해서 파일에 업로드를 하는 형태에서 사용될 수 있고 dumps는 단순히 메모리상에서 사용할 때 적용할 수 있다.
import json
a = [1,2,3,4,5]
with open("test.txt") as f:
json.dump(a,f)
dump_a: str = json.dumps(a)
참고로 dump를 진행할 때 두 매서드 모두 sort_keys: bool
, indent: int
옵션을 제공하는데 예를들어 dict 객체를 직렬화 하게 될 때 정렬을 할지, indent를 만들 것인지등을 설정할 수 있다.
load 는 반대로 직렬화했던 str 객체를 다시 객체로 바꿔주는 역할을 한다.
import json
a = [1,2,3,4,5]
with open("test.txt") as f:
b = json.load(f)
dump_a: str = json.dumps(a)
a: list = json.loads(dump_a)
pickle 또한 dump, dumps, load, loads 를 제공하고 바이트형태라는 점을 제외하고는 동일하다. 또한 pickle 은 custom class 또한 직렬화가 된다는 특징이 있다. 하지만 해당 객체가 참조하고 있던 정보들은 가져오지 못한다
import pickle
class B:
c = 1
class A:
a = 1
b = 2
def __init__(self, b: B):
self.b_instance = b
b = B()
a = A(b)
pickle_a = pickle.dumps(a)
unpickle_a = pickle.loads(pickle_a)
print(f"Pickle before: {a.b_instance} after: {unpickle_a.b_instance}")
# Pickle before: <__main__.B object at 0x1052adcd0> after: <__main__.B object at 0x1052c1fd0>
직렬화를 할 때 용도에 따라서 모듈을 잘 결정해서 사용하면 될 것 같다. custom class에 대한 직렬화가 필요하다면 pickle을 활용하고 단순 json 타입에 대한 데이터 송수신에서의 직렬화 역직렬화가 필요하다면 json 모듈을 사용하면 될 것 같다.