2013-12-17 1 views
4

피클을 사용할 때 정상적으로 작동하고로드가 덤프 될 수 있습니다.피클 덤프가 현재 파일 데이터를 대체합니다.

문제는 프로그램을 닫고 다시 덤프를 시도하면 기존 파일 데이터를 새 덤프로 바꿉니다.

import pickle 
import os 
import time 


dictionary = dict() 


def read(): 
    with open('test.txt', 'rb') as f: 
     a = pickle.load(f) 
    print(a) 
    time.sleep(2) 


def dump(): 
    chs = raw_input('name and number') 
    n = chs.split() 
    dictionary[n[0]] = n[1] 
    with open('test.txt', 'wb') as f: 
     pickle.dump(dictionary, f) 


Inpt = raw_input('Option : ') 
if Inpt == 'read': 
    read() 
else: 
    dump() 

답변

0

"wb" 모드에서 파일을 열면 파일을 잘라냅니다 - 즉, 파일의 내용을 삭제하고 당신이 그것에 작업 할 수 있습니다 : 여기 내 코드입니다.

일반적으로 파일을 추가 ("ab") 모드로 열면 끝에 데이터가 추가됩니다. 그러나 Pickle은 추가 기능을 지원하지 않으므로 데이터를 새 파일로 저장해야합니다 (다른 파일 이름을 사용하거나 사용자에게 묻거나 -o test.txt과 같은 명령 줄 매개 변수를 사용 하시겠습니까?). 프로그램이 실행됩니다.

관련 항목에 Pickle을 사용하지 마십시오. 안전하지 않아. 대신 JSON을 사용하는 것이 좋습니다 (표준 lib-import json에 있음).

+0

답변의 첫 번째 부분은 맞습니다 ...하지만 두 번째 부분은 올바르지 않습니다. 피클은 추가를 지원합니다. 그리고 "안전하지 않은"경우 float/str/list/dict 이외의 형식을 저장하려고하면 JSON은 확장 할 수 없으면 수행 할 수 없습니다.이 경우 피클처럼 안전하지 않게됩니다. 당신은 당신의 데이터와 당신이 그것을 어떻게 저장하길 원하는지를 알아야합니다. 그렇지 않으면 일반적인 안전 대답이 없습니다. – abarnert

+0

아닙니다. Pickle은 본질적으로 위험합니다 (모듈의 문서가 여러 번주의를 기울이며주의를 기울임). pickle.load' *는 pickled 파일에 포함 된 임의의 코드를 실행합니다 * : http : //michael-rushanan.blogspot .ca/2012/10/why-python-pickle-is-insecure.html –

+0

pickle이 위험한 이유를 이해하지 않으려는 경우 확장 JSON 또는 다른 방식을 사용하여 안전하지 않은 코드를 작성하게 될 것입니다. . 특히 경고 메시지는 "pickle 모듈은 잘못되었거나 악의적으로 생성 된 데이터에 대해 보안을 유지하기위한 것이 아닙니다." JSON을 확장하여 사용자 정의 클래스를 명백한 방식으로 저장하고 복원하는 경우 오류가 있거나 악의가있는 생성 된 데이터에 대해 안전하지 못합니다. – abarnert

7

w 모드 (또는 wb)로 파일을 열면 새로운 파일을 쓰고 이미 있던 파일이 지워집니다. 'A'(이미을 존재하는 경우 파일을 절단) 모드의

가장 일반적으로 사용되는 값을 쓰기 위해 읽기, 'w' 'R', 그리고 : the docs으로

말 추가의 경우 ...

즉, 'wb'이 아닌 'ab'을 사용하려고합니다.


그러나 동일한 파일에 새 덤프를 추가하면 여러 개의 개별 값으로 구성된 파일이됩니다. load 한 번만 호출하면 첫 번째 메시지가로드됩니다. 모두을로드하려면 해당 코드를 작성해야합니다. 예를 들어, loadEOFError까지 반복 될 수 있습니다.


정말, 무슨 당신이하려는 것은 피클 파일에 추가 할 수 없습니다처럼 보이지만 절인 사전을 기존을 수정합니다.

당신이 할 수있는 다음과 같이 함께 덤프의 모든 병합 부하와 기능 :

def Load(): 
    d = {} 
    with open('test.txt', 'rb') as f: 
     while True: 
      try: 
       a = pickle.load(f) 
      except EOFError: 
       break 
      else: 
       d.update(a) 
    # do stuff with d 

하지만 더미로 즉, 당신이 당신의 프로그램을 실행 번 더 느린 속도가 느린 얻을 것 동일한 값의 복사본이 점점 더 많아지고 있습니다. 이렇게하려면 오른쪽 이전 사전을로드하고 수정 한 다음 수정 된 버전을 덤프해야합니다. 그리고 그걸 위해서 w 모드를 원합니다.

그러나 적어도 키가 문자열 인 경우 사전을 유지하는 훨씬 더 좋은 방법은 dbm (값이 문자열 인 경우) 또는 shelve (그렇지 않은 경우)을 사용하는 것입니다.