130

辞書を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)
4

6 に答える 6

183

json モジュールを試しましたか? 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}
于 2012-06-14T05:14:27.987 に答える
107

あなたのコードはほぼ正しいです!あなたは正しいです、あなたはただ1つのステップを逃しています。ファイルを読み取るときは、文字列として読み取っています。しかし、文字列を辞書に戻したいとします。

あなたが見たエラーメッセージself.whipは、辞書ではなく文字列だったからです。したがって、文字列を辞書に変換する必要があります。

これが最も簡単な方法です: 文字列を にフィードしますeval()。そのようです:

def reading(self):
    s = open('deed.txt', 'r').read()
    self.whip = eval(s)

1行で実行できますが、次のようにすると面倒に見えると思います。

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)

「CPython」として知られる最も一般的な Python ではwith、組み込みの「ガベージ コレクション」機能がファイルの処理が完了したことを認識し、ファイルを閉じてくれるため、通常はこのステートメントは必要ありません。しかし、「Jython」(Java VM 用の Python) や「PyPy」(ジャストインタイム コード最適化を備えた非常にクールな実験システム) などの他の Python 実装では、ファイルを閉じることができない場合があります。を使う習慣をつけると良いですしwith、コードがかなり理解しやすくなると思います。

于 2012-06-14T05:20:12.273 に答える
75

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.txtself.whipself.whip

おそらく、文字列を評価して Python オブジェクトに戻したいでしょう。

self.whip = eval(open('deed.txt', 'r').read())

evalのように聞こえることに注意してくださいevil。それは意図的なものです。pickle代わりにモジュールを使用してください。

于 2012-06-14T05:14:09.857 に答える
8

私は本当にうまく機能する独自の関数を作成しました:

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)
于 2013-09-15T08:27:46.853 に答える
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')
于 2015-12-09T01:50:52.290 に答える