Написание файла dict в txt и его чтение?
Я пытаюсь написать словарь в txt файл. Затем прочитайте значения dict, набрав ключи с помощью raw_input
. Я чувствую, что просто пропустил один шаг, но теперь я искал какое-то время.
Я получаю эту ошибку
File "name.py", line 24, in reading
print whip[name]
TypeError: string indices must be integers, not str
Мой код:
#!/usr/bin/env python
from sys import exit
class Person(object):
def __init__(self):
self.name = ""
self.address = ""
self.phone = ""
self.age = ""
self.whip = {}
def writing(self):
self.whip[p.name] = p.age, p.address, p.phone
target = open('deed.txt', 'a')
target.write(str(self.whip))
print self.whip
def reading(self):
self.whip = open('deed.txt', 'r').read()
name = raw_input("> ")
if name in self.whip:
print self.whip[name]
p = Person()
while True:
print "Type:\n\t*read to read data base\n\t*write to write to data base\n\t*exit to exit"
action = raw_input("\n> ")
if "write" in action:
p.name = raw_input("Name?\n> ")
p.phone = raw_input("Phone Number?\n> ")
p.age = raw_input("Age?\n> ")
p.address = raw_input("Address?\n>")
p.writing()
elif "read" in action:
p.reading()
elif "exit" in action:
exit(0)
Ответы
Ответ 1
Ваш код почти прав! Вы правы, вы просто пропустили один шаг. Когда вы читаете в файле, вы читаете его как строку; но вы хотите превратить строку обратно в словарь.
Сообщение об ошибке, которое вы видели, было потому, что self.whip
была строкой, а не словарем.
Сначала я написал, что вы можете просто подставить строку в dict()
, но это не сработает! Вам нужно сделать что-то еще.
Пример
Вот самый простой способ: подайте строку в eval()
. Например:
def reading(self):
s = open('deed.txt', 'r').read()
self.whip = eval(s)
Вы можете сделать это в одной строке, но я думаю, что это выглядит грязно:
def reading(self):
self.whip = eval(open('deed.txt', 'r').read())
Но eval()
иногда не рекомендуется. Проблема в том, что eval()
будет оценивать любую строку, и если кто-то обманет вас запуском действительно сложной строки, может произойти что-то плохое. В этом случае вы просто запускаете eval()
в своем собственном файле, поэтому все должно быть в порядке.
Но поскольку eval()
полезен, кто-то сделал альтернативу этому, что безопаснее. Это называется literal_eval
, и вы получаете его из модуля Python под названием ast
.
import ast
def reading(self):
s = open('deed.txt', 'r').read()
self.whip = ast.literal_eval(s)
ast.literal_eval()
будет оценивать только строки, которые превращаются в базовые типы Python, поэтому нет никакой возможности, чтобы сложная строка могла сделать что-то плохое на вашем компьютере.
ИЗМЕНИТЬ
Собственно, лучшей практикой в Python является использование инструкции with
, чтобы убедиться, что файл закрыт правильно. Переписывая вышеприведенное, чтобы использовать инструкцию with
:
import ast
def reading(self):
with open('deed.txt', 'r') as f:
s = f.read()
self.whip = ast.literal_eval(s)
В самом популярном Python, известном как "CPython", обычно вам не нужен оператор with
, поскольку встроенная функция "сборка мусора" будет определять, что вы закончили с файлом и закроете его для тебя. Но другие реализации Python, такие как "Jython" (Python для Java VM) или "PyPy" (действительно классная экспериментальная система с оптимизацией кода только в момент времени), могут не найти возможности закрыть файл для вас. Хорошо привыкнуть использовать with
, и я думаю, что это делает код очень легким для понимания.
Ответ 2
Вы пробовали json module? Формат JSON очень похож на словарь python. И он доступен для чтения/записи:
>>> import json
>>> d = {"one":1, "two":2}
>>> json.dump(d, open("text.txt",'w'))
Этот код выгружается в текстовый файл
$ cat text.txt
{"two": 2, "one": 1}
Также вы можете загрузить из файла JSON:
>>> d2 = json.load(open("text.txt"))
>>> print d2
{u'two': 2, u'one': 1}
Ответ 3
Чтобы хранить объекты Python в файлах, используйте модуль pickle
:
import pickle
a = {
'a': 1,
'b': 2
}
with open('file.txt', 'wb') as handle:
pickle.dump(a, handle)
with open('file.txt', 'rb') as handle:
b = pickle.loads(handle.read())
print a == b # True
Обратите внимание, что я никогда не устанавливал b = a
, а вместо этого травил a
на файл, а затем рассыпал его в b
.
Что касается вашей ошибки:
self.whip = open('deed.txt', 'r').read()
self.whip
был объектом словаря. deed.txt
содержит текст, поэтому, когда вы загружаете содержимое deed.txt
в self.whip
, self.whip
становится строковым представлением самого себя.
Вероятно, вы захотите оценить строку обратно в объект Python:
self.whip = eval(open('deed.txt', 'r').read())
Обратите внимание, как eval
звучит как evil
. Это намеренно. Используйте вместо этого модуль pickle
.
Ответ 4
Я создал свои собственные функции, которые работают очень красиво:
def writeDict(dict, filename, sep):
with open(filename, "a") as f:
for i in dict.keys():
f.write(i + " " + sep.join([str(x) for x in dict[i]]) + "\n")
Сначала он сохранит имя ключа, а затем все значения. Обратите внимание, что в этом случае мой dict содержит целые числа, поэтому он преобразуется в int
. Скорее всего, это часть, которую вам нужно изменить для вашей ситуации.
def readDict(filename, sep):
with open(filename, "r") as f:
dict = {}
for line in f:
values = line.split(sep)
dict[values[0]] = {int(x) for x in values[1:len(values)]}
return(dict)
Ответ 5
Вы можете выполнить итерацию через пару ключ-значение и записать ее в файл
pair = {'name': name,'location': location}
with open('F:\\twitter.json', 'a') as f:
f.writelines('{}:{}'.format(k,v) for k, v in pair.items())
f.write('\n')
Ответ 6
Привет, есть способ написать и прочитать словарь в файл, вы можете превратить свой словарь в формат JSON и быстро и быстро читать и писать:
чтобы написать свою дату:
import json
your_dictionary = {"some_date" : "date"}
f = open('destFile.txt', 'w+')
f.write(json.dumps(yout_dictionary))
и прочитать ваши данные:
import json
f = open('destFile.txt', 'r')
your_dictionary = json.loads(f.read())