【问题标题】:Writing a dict to txt file and reading it back?将 dict 写入 txt 文件并将其读回?
【发布时间】:2012-06-17 02:58:19
【问题描述】:

我正在尝试将字典写入 txt 文件。然后通过键入带有raw_input 的键来读取dict 值。我觉得我只是错过了一步,但我已经找了一段时间了。

我收到此错误

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)

【问题讨论】:

  • 这段代码有什么问题?
  • name 'p' is not defined, p 应该是 Person 类的实例

标签: python


【解决方案1】:

你试过the 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}

【讨论】:

  • 您是否应该在with 语句中打开文件进行读/写以确保它在之后关闭?
  • 哇,太美了。
  • 我在一些复杂的字典上使用这种方法时遇到了问题,比如有嵌套的集合值(例如d = {"one": {"1" : 1, "a": {"i"}}})。因此,我推荐 @blender 的 pickle 方法适用于我的情况。
  • 请注意,python 的 json 在执行 json.dump 时会将 dict 键转换为 strings,因此在执行 json.load 时,json.dump({1: 'one'}, file) 将读回为 {'1': 'one'}。如果您不打算使用 Python 以外的其他语言读取保存的文件,则最好使用 pickle。
  • 有没有办法使用类似 json.dumps( dict_x, indent=4) 的方法来格式化 dict 写入文件的方式以使其更清晰?当我使用你的代码时,整个 dict 都会写入一行,无论它有多大,而且它不容易被人类阅读。
【解决方案2】:

您的代码几乎正确!你是对的,你只是少了一步。当您读入文件时,您将其作为字符串读取;但你想把字符串转回字典。

您看到的错误消息是因为self.whip 是一个字符串,而不是字典。所以你需要将字符串转换为字典。

示例

这是最简单的方法:将字符串输入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() 将评估 any 字符串,如果有人欺骗你运行一个非常棘手的字符串,可能会发生一些不好的事情。在这种情况下,您只是在自己的文件上运行eval(),所以应该没问题。

但是因为eval() 很有用,所以有人做了一个更安全的替代方案。这称为literal_eval,您可以从名为ast 的Python 模块中获取它。

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”(用于 Java VM 的 Python)或“PyPy”(具有即时代码优化的非常酷的实验系统)可能无法为您关闭文件。养成使用with 的习惯很好,我认为它使代码非常容易理解。

【讨论】:

  • dict() 需要字典或元组列表。它不会评估字符串。
  • @Blender 哦,你说得对,我累了。我会编辑答案。
  • @Nick:先尝试运行它;)
  • @Blender,感谢您的提醒。由于我累了,我想我将不再在 StackOverflow 上发帖了! :-)
【解决方案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 模块。

【讨论】:

  • 不,它给了我这个错误文件“name.py”,第 24 行,在阅读 printwhip[name] 类型错误:字符串索引必须是整数,而不是 str 我认为 p = Person() 定义了它
  • 该文本不在您的代码中。在提出问题之前,请先说明问题所在。
  • 要将 Python 对象存储在文件中,请使用 pickle 模块 除非这些是配置文件,因此您希望它们可以被人工编辑 - 请参阅 Why bother with python and config files?
  • 完美。这正是我所需要的:将本机 python 结构状态存储在一个不打算供用户编辑的文件中。
  • 这种方法非常适用于复杂的字典,正如我在我对@KFL 建议的 JSON 方法的评论中所描述的那样
【解决方案4】:

您好,有一种方法可以将字典写入和读取到文件中,您可以将字典转换为 JSON 格式并快速读取和写入,只需这样做:

写下你的日期:

 import json

 your_dictionary = {"some_date" : "date"}
 f = open('destFile.txt', 'w+')
 f.write(json.dumps(your_dictionary))

并读取您的数据:

 import json

 f = open('destFile.txt', 'r')
 your_dictionary = json.loads(f.read())

【讨论】:

    【解决方案5】:

    我创建了自己的功能,效果非常好:

    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)
    

    【讨论】:

    • 如果您的值不太长,则代码很棒。我的字典包含多个刚刚被“...”截断的长字符串
    【解决方案6】:

    您可以遍历键值对并将其写入文件

    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')
    

    【讨论】:

      猜你喜欢
      • 2018-08-09
      • 2013-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-19
      • 2020-02-20
      相关资源
      最近更新 更多