zenn.skin 무료버전 배포중!
자세히보기

Python/Syntax

[Python] Pickle

koosco! 2021. 12. 11. 19:42

1. Pickle?

- 객체를 저장할 때 사용할 수 있는 라이브러리

- 객체를 직렬화(Serialize)하고 역직렬화(Deserialize)할 수 있게 해준다

    - 직렬화: 객체의 데이터를 바이트로 바꾸어 저장

    - 역직렬화: 바이트로 저장된 데이터를 다시 원래의 객체로 복원

- 객체는 문자열처럼 일반 텍스트로 저장할 수 없기 때문에 바이너리로 바꾸어 저장해야 한다

- 바이너리로 저장된 파일은 읽을 수 없지만 저장, 전송에 효율적임

- 바이너리로 저장된 파일은 txt가 아닌 bin형식으로 저장

2. Pickle의 사용법

- pickle.dump(객체, "파일이름") 를 이용해 객체를 직렬화

- pickle.load("파일이름") 를 이용해 객체를 역직렬화

 

 

3. Pickle을 이용한 객체 저장

1) List 저장

L = list('abcd')

with open('pickle_example.txt', 'w') as file:
    file.write(L)

위와 같이 리스트를 txt로 저장하려 하면 아래와 같이 TypeError가 발생한다.

(write메서드는 문자열만 인수로 받기 때문)

TypeError: write() argument must be str, not list

 

pickle 라이브러리를 사용하면 정상적으로 파일을 저장할 수 있다. 이 때, 옵션에 쓰기 옵션인 "w"와 "b" 옵션을 같이 주면 바이너리로 저장할 수 있다.

 

import pickle

L = list('abcd')
with open('pickle_example.bin', 'wb') as file:
    pickle.dump(L, file)

바이너리로 저장된 것을 확인할 수 있다

 

 

2) List, Dict, Str 저장

list 이외에도 파이썬 객체면 모두 pickle 라이브러리를 이용해 파일에 저장할 수 있다

import pickle

class SimpleClass(object):
    def __init__(self):
        self.x = 10
        self.y = 20
        
L = list('abcd')
D = {'a': 1, 'b': 2, 'c': 3}
S = "abcde"

with open('pickle_example.bin', 'wb') as file:
    pickle.dump(L, file)
    pickle.dump(D, file

with open('simpleclass.bin', 'wb') as file:
    pickle.dump(SimpleClass, file)

리스트와 딕셔너리, 문자열을 pickle을 이용해 bin 파일로 저장

 

import pickle

with open('pickle_example.bin', 'rb') as file:
    data_list = []
    while True:
        try:
            data = pickle.load(file)
        except EOFError:
            break
        data_list.append(data)
print(data_list)

pickle.load를 이용해 객체를 다시 불러오는 것이 가능하다

[['a', 'b', 'c', 'd'], {'a': 1, 'b': 2, 'c': 3}, 'abcde']

 

3) 사용자 정의 클래스의 인스턴스

- 사용자 정의 클래스 저장 파일

import pickle

class SimpleClass(object):
    def __init__(self):
        self.x = 10
        self.y = 20
    
    def set_z(self, z):
        self.z = z

S1 = SimpleClass()
S1.set_z(30)

if __name__ == '__main__':
    with open('simpleclass.bin', 'wb') as file:
        pickle.dump(S1, file)

 

- 사용자 정의 클래스 불러오기 파일

import pickle
from openfile import SimpleClass

with open('simpleclass.bin', 'rb') as file:
    S1 = pickle.load(file)

print(S1.x, S1.y, S1.z)

- 주의할 점은 pickle은 dump할 때 클래스에 대한 내용은 저장하지 않는다는 것

- 클래스를 불러오기 전에 python 파일에서 클래스 구조를 미리 불러와야 pickle.load를 할 때 정상적으로 인스턴스를 불러올 수 있다

 

4. RCE(Remote Code Execution) 취약점

- pickle 라이브러리는 안전하지 않음

- pickle 라이브러리의 load 메소드는 RCE취약점 문제가 있으므로 사용에 있어 주의를 해야한다

- RCE란 외부에서 전송된 코드가 실행되는 취약점을 말한다

- 그러므로 외부에서 받은 pickle은 절대 받지 않도록 주의한다

'Python/Syntax'의 다른글

  • 현재글 [Python] Pickle

관련글