-1

スペイン語のコードで申し訳ありませんが、それ以外に、その構造を理解できるはずです。私は Python 3.3.2 を使用しており、ここで問題が発生しています。

leyendoestadisticas = open("listas\Estadisticas.txt", "r")
bufferestadisticas = leyendoestadisticas.read()
leyendoestadisticas.close()
if not '"'+user.name+'"' in bufferestadisticas: #If name is not found, do this
  escribiendoestadisticas = open("listas\Estadisticas.txt", 'a')
  escribiendoestadisticas.write(json.dumps([user.name, palabrasdelafrase, letrasdelafrase,
                                            "1", user.nameColor, user.fontColor, user.fontFace, user.fontSize, message.body, room.name])+"\n")
  escribiendoestadisticas.close()
else: #If name is found...
  data = []
  with open('listas\Estadisticas.txt', 'r+') as f:
    for line in f:
      data_line = json.loads(line)
      if data_line[0] == user.name: #if name matches...
        if data_line[9] == room.name: #And room also, then update info.
          data_line[1] = int(data_line[1])+int(palabrasdelafrase)
          data_line[2] = int(data_line[2])+int(letrasdelafrase)
          data_line[3] = int(data_line[3])+1
          data_line[4] = user.nameColor
          data_line[5] = user.fontColor
          data_line[6] = user.fontFace
          data_line[7] = user.fontSize
          data_line[8] = message.body
          data_line[9] = room.name
        else: #but if name is found and room doesn't matches. #PROBLEM HERE
          escribiendoestadisticas = open("listas\Estadisticas.txt", 'a')
          escribiendoestadisticas.write(json.dumps([user.name, palabrasdelafrase, letrasdelafrase,
                                                  "1", user.nameColor, user.fontColor, user.fontFace, user.fontSize, message.body, room.name])+"\n")
          escribiendoestadisticas.close()
      data.append(data_line)
      break
    f.seek(0)
    f.writelines(["%s\n" % json.dumps(i) for i in data])
    f.truncate()

その目的は、行のプロパティ 9 が一致する限り、user.name を追加してその情報を更新することです。一致しない場合は、同じ user.name でプロパティ 9 の新しい値を持つ新しい行をリストに追加します。

プロパティ 9 が一致する場合は完全に機能しますが、一致しない場合は、その user.name の既存の値を上書きし、[1]、[2]、および [3] のプロパティを最初からカウントし始めます。

助けてくれてありがとう。

編集:回答からの情報で更新:

else: 
  data = []
  with open('listas\Estadisticas.txt', 'r+') as f:
    lines = f.readlines()
  for line in lines:
    data_line = json.loads(line)
    if data_line[0] == user.name: 
      if data_line[9] == room.name:
        data_line[1] = int(data_line[1])+int(palabrasdelafrase)
        data_line[2] = int(data_line[2])+int(letrasdelafrase)
        data_line[3] = int(data_line[3])+1
        data_line[4] = user.nameColor
        data_line[5] = user.fontColor
        data_line[6] = user.fontFace
        data_line[7] = user.fontSize
        data_line[8] = message.body
        data_line[9] = room.name
      data.append(data_line)
  f.seek(0)
  f.writelines(["%s\n" % json.dumps(i) for i in data])
  f.truncate()
  for line in lines: 
    data_line = json.loads(line)
    if data_line[0] == user.name: 
      if not data_line[9] == room.name:
        escribiendoestadisticas = open("listas\Estadisticas.txt", 'a')
        escribiendoestadisticas.write(json.dumps([user.name, palabrasdelafrase, letrasdelafrase,
                                                "1", user.nameColor, user.fontColor, user.fontFace, user.fontSize, message.body, room.name])+"\n")
        escribiendoestadisticas.close()

しかし、今はエラーが発生しています: ValueError: I/O operation on closed file. 完全に失われました。

4

1 に答える 1

0

読み取り中にファイルを変更しているようです。最初にファイルを完全にロードし、コンテキスト ハンドラにファイルを閉じさせます。

else: #Si está, suma datos
  data = []
  with open('listas\Estadisticas.txt', 'r+') as f:
      lines = f.readlines()

  for line in lines:
    data_line = json.loads(line)
    if data_line[0] == user.name: #if name is found...
      if data_line[9] == room.name: #And room also, then update info.
        data_line[1] = int(data_line[1])+int(palabrasdelafrase)
        [etc]

他の人がコメントで示したように、おそらくuser.name行ごとではなく、ファイル全体を検索する必要があります。

また、@abarnert が指摘するようdataに、ループ内で変更するだけでなく、最後に完全な情報セットを書き出します。


いくつかの一般的なコメント:

  • data_line10 個未満のアイテムが含まれている場合、コードはケースを処理しません。これが発生すると、プログラムがクラッシュします。

  • json全体dictをファイルに保存するために使用する方がはるかに良いでしょう。このようにして、 をロードするdictと、すぐに をチェックしてアクセスできますuser.nameuser.name辞書のキーを作成することをお勧めします。

次のようになります (編集: user.name と room.name の一意の組み合わせが必要であることがわかりました):

with open('listas\Estadisticas.json', 'rb') as f:
    data = json.load(f)

key = (user.name, room.name)

if key in data:
    data[key]['nameColor'] = user.nameColor
    [...etc...]
else:
    # I am not sure what details are different
    data[key] = {} # New sub-dict
    data[key]['nameColor'] = user.nameColor
    [...etc...]

with open('listas\Estadisticas.json', 'wb') as f:
    json.dump(f, data)
  • 名前は変更できます。これが、データベースが通常、人の名前や部屋の名前ではないキーを使用する理由です。物事の名前を数字などの抽象的なものに割り当ててから、表示が必要なときに名前を調べることをお勧めします。ユーザーの名前が最初に間違って入力され、後で名前のスペルを修正したい場合、すべてのデータが失われることを意味するため、修正できないことを説明するのに苦労します...
于 2013-09-17T21:58:49.017 に答える