본문 바로가기

devlog/Python

직렬화(Serialize), 역직렬화(Deserialize), 마샬링(Marshalling)

직렬화와 역직렬화는 일상에서 쓰이지 않는 용어로 단어만 봐서는 무슨뜻인지 한 번에 알 수 없었다.
소켓 통신 프로그램, API를 개발하거나 타사 API를 사용하면서야 개념이 와닿았다.
가끔 헷갈리기도 하는 이 두 개념 직렬화, 역직렬화를 정리한다.

What? 사전적 의미


컴퓨터과학에서 직렬화란 나중에 객체를 다시 재생성할 수 있게 저장하는 과정을 의미한다.

직렬화(Serialize)

직렬화는 데이터를 보내는 쪽에서 데이터 구조(data structure) 또는 객체(object)를 저장하거나 네트워크를 통해 전송할 수 있는 형식으로 변환하는 작업을 의미한다. 데이터를 받는 쪽에서는 받은 비트 데이터를 직렬화 형식에 따라 다시 읽어들여 오브젝트 또는 데이터 구조로 재조립하는데 사용할 수 있다. 따라서 객체나 데이터 구조가 여러 객체를 참조를 갖고있고 복잡하다면 직렬화가 간단하지 않게 된다. 또한 Java와 같은 객체지향 직렬화에서는 메서드가 포함되지 않는다. 객체 직렬화 과정은 경우에 따라 객체 마샬링이라고도 한다.

역직렬화(Deserialize)

직렬화를 통해 받은 데이터는 1과 0으로 이루어진 비트 데이터의 모음일 것이다.
일련의 비트 데이터에서 원래 데이터 구조 또는 객체를 추출하는 작업을 역직렬화라고 한다.

How? 그래서 어떻게 쓰는건데?

직렬화는 특정 언어에 종속적인 개념이 아니다.
아래 캡쳐 화면은 직렬화를 구글링하면 나오는 결과 중 첫번째 페이지다. 1개를 제외하고는 다 JAVA 직렬화에 대해 설명하고 있다.

 

남들과는 다르게 하고싶어서

편리하고도 꽤 재밌는 Python의 직렬화 방법을 알아보자.

pickle 모듈을 이용한 직렬화/역직렬화

pickle은 파이썬 객체 구조의 직렬화/역직렬화를 위한 바이너리 프로토콜을 구현한 모듈이다.
pickle - 파이썬 객체 직렬화 docs

주의할 점은 신뢰할 수 없는 데이터를 역직렬화 시 임의의 코드를 실행하는 취약점이 구성될 수 있다. 그러므로 신뢰할 수 없는 데이터 또는 변조된 데이터는 절대로 역직렬화 하면 안된다. 이런 경우 json 모듈 사용이 더 적합하다.

pickle에 사용할 수 있는 프로토콜을 지정하기도 하는데 높은버전의 프로토콜은 높은 버전의 파이썬이 필요하다.
해당 내용은 피클링에 쓸 수 있는 6가지 프로토콜 참고하면 된다.

아래 예제는 파이썬 위키 pickle 예제Using Pickle에서 파일 입출력 부분을 수정한 코드이다.

import pickle

# lion과 kitty가 좋아하는 색깔을 딕셔너리 타입으로 정의
color = { "lion": "yellow", "kitty": "red" }

# save.p 파일을 바이너리 쓰기 모드로 열기
with open('save.p', 'wb') as f:
    # color를 직렬화하여 파일에 쓴다.
    pickle.dump(color, f)

# save.p를 바이너리 읽기 모드로 열기
with open('save.p', 'rb') as f:
    # 파일 내용을 역직렬화하여 color2에 저장하고 출력
    color2 = pickle.load(f)
    print(color2)

json 모듈을 이용한 직렬화/역직렬화

파이썬 json은 JSON(Javascript Object Notation) 파일과 데이터의 직렬화/역직렬화를 위한 모듈이다.
JSON은 사람이 읽을 수 있고 텍스트를 직렬화 하며 파이썬뿐 아니라 다른 여러 언어에서도 상호 운용 가능하다.
pickle과 다르게 신뢰할 수 없는 JSON의 역 직렬화 시 임의 코드 실행 취약점이 생기지 않는다.

Why? 왜 쓰는가?


  • 네트워크 망으로 연결된 서로 다른 프로그램이 공통된 데이터 구조를 송신, 수신 하기위한 용도
  • 데이터 DB, 하드디스크 등 저장 매체에 저장하기 위한 용도
  • SOAP 프로토콜 같은 원격 프로시저 호출(RPC)를 통해 원격지에 위치한 메소드를 로컬에 있는 메소드처럼 사용할 수 있게 하기 위한 용도
  • REST (RRpresentational State Transfer) 아키텍처를 준수한 API 사용 시