蛇使いな彼女BLOG
第63回】 研究会応答編②ー辞書の保存とパスについて #1.
2022.07.15
皆さんこんにちは。
前回に引き続き、今回もアプリケーションに関する質問に答えますのコーナーです。
一応これが最後の回答です!
■入力したテキスト(辞書)の保存ができたらいいな~/パスの挙動について
一般的なアプリケーションだと、設定ボタンなどから手動で変更した項目は保存されて、次回以降起動したときはその設定が適応されるのが普通ですよね?
今回それを実現するために簡単な方法をご紹介します♬
あと、ついでにパスの扱いについてもサラッと説明しておきますね。
【辞書の保存】
一般的な方法として、pickleやJSON、NumPyを使うことが多いようです。
NumPyは数値計算用のライブラリなので、この記事を遡ってみると書き込む数値の桁数などを指定出来ることから水質データなどCSV形式のデータの書き換えやデータ保存に使用していたような気がします。
*例*:
np.savetxt(new_path, rd, delimiter='
',header=firstrow,comments='',
fmt=["%.6f", "%.2f", "%.0f","%.2f", "%.2f", "%.2f","%.0f", "%.2f",
"%.1f","%.1f"])
こういった機能の他にもNumPyにはsave関数を使って任意の辞書を「.npy」拡張子のバイナリファイルとしても保存できるようです。
ですが、NumPy以外では開くことの出来ないファイル形式なので使う機会はかなり制限されます。(私も初めて知りました(笑))
NumPyのsaveに同じく、pickleによって作成されるデータフォーマットもPython固有のものなので、他のプログラミング言語への互換性はありませんが、“ポインター共有を表わすことができないといったような制限を受けることがない(-公式)”点に関しては利点のようです。
これは恐らく、JSONポインターなど、JSON独自の構文をPythonプログラムで表示出来ないという制限が掛かることがないという意味だと思います(検証したわけではありません💦)。
一方で、JSONはJavaScript Object Notationの略でJavaScriptのオブジェクトの書き方を元にしたデータ定義方法であり、Javaとの相性が良いのは勿論ですがその他のPython、C、PHPなど幅広いプログラミング言語でも共通して使用できる便利なツールです。
このような背景から、今回はJSONを使ってテキスト辞書をフォーマットしたいと思います。
実装環境を再現するためにこのような簡易GUIで説明していきますね。
SaveNameは保存するJSONファイルの名前、No.0~No.3まではそれぞれテキストを入力します。
次にSAVEボタンを押すと入力テキストをJSONファイルにフォーマットし、ローカル環境に保存されます。
OpenFileで先ほど作成したJSONファイルの中身を確認できます。流れはこんな感じです。
【Pythonスクリプト全体】↓
スクリプトコードは上から、GUIのレイアウト(6~16行)、ウインドウの生成(21行)、ボタンを押したときのイベント処理(25~69行)、ウインドウの起動(73~83行)という行程で記述しています。
おさらいですが、GUI画面からボタンウィジェットをマウスクリックすると、Python上ではイベントとして、ボタンウィジェットに設定したkeyの値が返ってきます。
右上の×ボタンを押すと返値はNoneです。イベントが起こる度に、押されたウィジェットのkey値(event)と、その他全てのウィジェットのkey値、入力値が参照できます(values)。
それを踏まえてまず入力値をJSONファイルに保存するメソッドを見てみましょう。
def save_func():
mydict={}
if values['NAME'] not in (None,'') : # SaveNameが入力されている場合
w['TXT'].update(text_color='white') # SaveNameのテキストの色を白に変更する
for i in range(4): # range(4): の4=入力欄の数
item_txt=values['item{}'.format(i)] # 入力欄に設定したKey値から入力値を参照
if item_txt != None: #mydictに書き込み
mydict[i] = item_txt
elif item_txt == None:
mydict[i] = 'item{}'.format(i)
# テキスト保存
savefile=values['NAME']+'.json' # ファイル名
with open(savefile,"w") as f: # mode=’w’で書き込み用のファイルを開く
json.dump(mydict, f) # 辞書を保存
w['TXT2'].update('入力されたテキストを '+savefile +' に保存しました。')
json.dunm()で簡単にテキストオブジェクトをJSONにフォーマットしてくれます。ここで注意する点ですが、JSONはstr(文字列)形式を生成するのでbytes(バイナリ)形式は使用できません。with open(savefile,"wb") as f: と書いてしまうと、バイナリ形式の書き込みとなるので、このようにエラーがでます。↓
Pickleでフォーマットする場合はバイナリ形式が使用可能なので
with open(savefile,"wb") as f:
pickle.dump(mydict, f)
のように書き換えても動作します。
JSONとpickleはフォーマット時のコードが似ているので、状況によって使い分けても良さそうですね。
保存に成功すると、入力した名前でJSONファイルが作成されます!
今回はwith open(savefile,"w") as f: と、絶対パスを指定していないので今開いているスクリプトと同じ階層にファイルが保存されます。
今回はここまでにして、この続きとパスに関しては次回説明します。