2015-07-15 2 views
2

Очень новичок программист, извините, если это глупо или если мой английский неверен. Итак, у меня есть эта адресная книга в командной строке, которую я пишу. Он состоит из словаря, который содержит объект с ключом в качестве переменной имени, и каждый объект имеет связанные с ним переменные, такие как имя человека, адрес электронной почты и т. Д. Он работает, но теперь я пытаюсь сделать он сохраняет словарь постоянно в памяти с использованием рассола.EOFerror в непокрывающемся словаре Python из пустого файла соленья

def create_person(): 
    """Adds an instance object of the Person class to the dictionary persons. persons is a global variable, that has been created previously. DATA is a variable that points to a file named test.data that exists in the same directory as the script.""" 
    name = raw_input("Enter the person's name here: ") 
    email = raw_input("Enter the person's email here: ")  
    phone = raw_input("Enter the person's phone here: ") 
    address = raw_input("Enter the person's address here: ") 
    f = open(DATA, "rb") 
    persons = pickle.load(f) #assign whatever is saved in the dictionary in persistent memory to global variable persons, which is empty at this point in the beginning 
    f.close() 
    persons[name] = Person(name, email, phone, address)  
    f = open(DATA, "wb") 
    pickle.dump(persons, f) 
    f.close() 

Однако, я получаю эту ошибку:

Traceback (most recent call last): 
File "testpickle.py", line 85, in <module> 
    main() 
File "testpickle.py", line 40, in main 
    create_person() 
File "testpickle.py", line 20, in create_person 
    persons = pickle.load(f) 
File "/home/pedro/anaconda/lib/python2.7/pickle.py", line 1378, in load 
    return Unpickler(file).load() 
File "/home/pedro/anaconda/lib/python2.7/pickle.py", line 858, in load 
    dispatch[key](self) 
File "/home/pedro/anaconda/lib/python2.7/pickle.py", line 880, in load_eof 
    raise EOFError 
EOFError 

Я не понимаю этого. Я на самом деле уже написал эту программу, и она работала с сохранением памяти, но я случайно удалил ее. Что происходит?

+2

Вы уверены, что определение класса 'Person' точно так же, как это было до аварии? Это одна из возможных причин. – martineau

+2

Я настоятельно рекомендую вам не использовать 'pickle' практически для любых целей, потому что механизм очень хрупкий. Как ранний Pythoner, концепция интерфейса pickle была соблазнительной: «Я могу сохранить свои объекты и вернуть их без усилий». К сожалению, поскольку маринованные данные реализованы в виде программ для простой стековой машины, однобитовая ошибка разрушит все это. Ваш код выглядит правильно, но [тихие ошибки] (http://stackoverflow.com/questions/10263564/python-pickling-dictionary-eoferror) могут вторгнуться. Вместо этого используйте [sqlite3] (https://docs.python.org/2/library/sqlite3.html). – msw

+0

@martineau Класс Person не совсем то же самое, но от него ничего не должно измениться. Все, что я сделал, это удалить одну из переменных (отношений). – chilliefiber

ответ

3

pickle удара EOF верный сказать, что файл поврежден (возможно усеченный, может быть, операция записи не удалось).

Если вы загрузите его где-нибудь, мы сможем определить, что именно с ним не так. В худшем случае вам придется заглянуть внутрь и вывести данные, которые были там, чтобы повторно ввести его вручную.

Это ваша цена за использование нечитаемого формата и не обращая внимания на его целостность (например, writing to another file and only moving it over the original one after saving succeeded).

UPDATE:

Если вы хотите начать с новой, «пустой» файл в, а затем обработать случай, когда файл отсутствует и производят пустой dict. В конце концов, файл -, предположительно, должен отсутствовать, не так ли?

Пустой файл недействителен pickle данных (он должен содержать хотя бы информацию об объекте).

Вот «один очевидный путь» ((с) Python Zen) для обработки отсутствующего файла:

import errno  
try: f = open(DATA, "rb") 
except IOError,e: 
    if e[0]==errno.ENOENT: persons={} 
    else: raise 
else: 
    persons = pickle.load(f) 
    f.close() 
    del f 
+0

Что? Нет. Файл, который у меня был ранее, был удален. DATA - это совершенно новый файл. Я не интересуюсь тем, что было в файле, и тем, что будет в этом новом. Я просто пишу это, чтобы практиковать свой питон. – chilliefiber

+1

'pickle' удара' EOF' является уверенным сказать, что файл поврежден. Почему это коррумпированный вопрос - еще один вопрос. –

+0

Что делать, если я создаю новый файл, что-то вроде newfile.data, поместил его в тот же каталог, что и скрипт, а затем указал на него DATA, будет ли он работать? – chilliefiber

2

Я не вижу ничего явно неправильного с вашим кодом, но если вы просто хотите хранить пары ключ/значение, как это, вероятно, вы должны использовать модуль shelve вместо домашнего решения.

import shelve 

persons = shelve.open(DATA) 

def create_person(): 
    """Adds an instance object of the Person class to the dictionary persons. persons is a global variable, that has been created previously. DATA is a variable that points to a file named test.data that exists in the same directory as the script.""" 
    name = raw_input("Enter the person's name here: ") 
    email = raw_input("Enter the person's email here: ")  
    phone = raw_input("Enter the person's phone here: ") 
    address = raw_input("Enter the person's address here: ") 
    persons[name] = Person(name, email, phone, address)  

while more_people: 
    create_person() 

persons.close()  
+0

Я честно понятия не имею, что происходит с рассолом. Только вчера он работал нормально.Затем я потерял рабочую версию, сегодня начал с нуля, и она не работает по неизвестным причинам. Должен ли я размещать весь свой код где-нибудь? Это поможет? – chilliefiber

+2

@pedromatias Возможно, вы повредили свой файл, нажав Ctrl-C или закрыв окно сценария во время выполнения. Попробуйте удалить файл и начать с чистого листа. Кроме того, я бы рекомендовал делать резервную копию файла регулярно (или лучше, автоматически), независимо от того, используете ли вы рассол или полку. Вы можете вернуть свой сценарий к последней хорошей версии, если основная копия будет повреждена. – hosford42

+0

Мне все равно, что в файле. Я действительно начал с нового файла DATA, DATA-файл является новым и пустым. Меня не волнует то, что я вкладываю туда, или вещи, которые были в старом файле. Это всего лишь проект для меня, чтобы работать над Python. Я просто хочу, чтобы мой код работал, а не из-за того, что я вложу в файл DATA. Старый файл DATA имел только информацию из 1 человека в качестве теста, и я был тем человеком xD – chilliefiber

Смежные вопросы