Травление списка — ошибка

#python #pickle

#python #маринование

Вопрос:

Когда я пытаюсь внести изменения в свой список, а затем загрузить его, я получаю сообщение об ошибке:

 Traceback (most recent call last):
  File "C:UsersTDesktoppickle_processpickle_process.py", line 16, in <module>
    print (library[1])
IndexError: string index out of range
 

Пожалуйста, предложите решение
Мой код:

 import pickle

library = []

with open ("LibFile.pickle", "ab") as lib:
    user = input("give the number")
    print ("Pickling")
    library.append(user)
    pickle.dump(user, lib)
    lib.close()

lib = open("LibFile.pickle", "rb")
library = pickle.load(lib)
for key in library:
    print (library[0])
    print (library[1])
 

Ответ №1:

Это не имеет ничего общего с травлением. Я напишу новый пример кода, который покажет, почему он не работает.

 library = []
library.append("user_input_goes_here")
print(library[0])
# OUTPUT: "user_input_goes_here")
print(library[1])
# IndexError occurs here.
 

Вы добавляете только одну вещь в свой пустой список. Как вы думаете, почему есть два элемента? 🙂

Если вы делаете это несколько раз, происходит сбой, потому что вы открываете файл pickle в режиме 'ab' вместо 'wb' . Вы должны перезаписывать pickle каждый раз, когда пишете в него.

 import pickle

library = ["index zero"]
def append_and_pickle(what_to_append,what_to_pickle):
    what_to_pickle.append(what_to_append)
    with open("testname.pkl", "wb") as picklejar:
        pickle.dump(what_to_pickle, picklejar)
        # no need to close with a context manager

append_and_pickle("index one", library)
with open("testname.pkl","rb") as picklejar:
    library = pickle.load(picklejar)

print(library[1])
# OUTPUT: "index one"
 

Это может показаться нелогичным, поскольку вы «добавляете» в список, но помните, что после того, как вы выделяете объект, это уже не список, а файл pickle. На самом деле вы не добавляете в ФАЙЛ при добавлении элемента в список, вы изменяете сам объект! Это означает, что вам нужно полностью изменить то, что написано в файле, чтобы он описывал этот новый объект с добавлением дополнительного элемента.

Ответ №2:

Вы перебираете объект, возвращаемый load функцией, и по какой-то причине пытаетесь получить доступ к объекту через индексы. Изменить:

 for key in library:
    print (library[0])
    print (library[1])
 

Для:

 for key in library:
    print key
 

Library[1] не существует, отсюда string index out of range и ошибка.

Комментарии:

1. это помогает, но по-прежнему не вносит изменений в мой список, он запоминает только первую запись

2. Вы добавляете только один раз: library.append(user) поэтому второй записи нет.

3. но затем, когда я закрываю программу и ввожу новый номер, он не сохраняет его в списке

4. @JoeDoe смотрите мой ответ — вам нужно открыть файл pickle в 'wb' режиме, а не 'ab' в режиме.