1. ホーム
  2. python

[解決済み] dict を txt ファイルに書き、それを読み取る?

2022-07-15 04:29:08

質問

辞書をtxtファイルに書き込もうとしています。次に、キーをタイプしてdictの値を読み取るには raw_input . 私はちょうど1つのステップを逃しているような気がしますが、私は今しばらく探しています。

私はこのエラーを取得します

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)

どのように解決するのですか?

あなたのコードは ほぼ正しい ! その通りです。ただ、一歩抜けています。 ファイルを読み込むとき、あなたはそれを文字列として読んでいます。しかし、あなたは文字列を辞書に戻したいのです。

あなたが見たエラーメッセージは 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の基本的な型に変わる文字列のみを評価するので、トリッキーな文字列がコンピュータ上で悪さをすることはあり得ません。

EDIT

実際、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 文は必要ありません。組み込みのガベージコレクション機能が、あなたがファイルから離れると判断してファイルを閉じます。 しかし、他のPython実装、例えばJython(Java VM用Python)やPyPy(ジャストインタイムコード最適化を備えた本当にクールな実験システム)は、あなたのためにファイルを閉じることを理解しないかもしれません。 を使う習慣をつけるとよいでしょう。 with を使う習慣をつけるのはいいことだと思います。