Pythonを真面目にゆっくり学ぶべく
を参考に学んでいきます*1。
前回
8. ファイルの入出力
8.2 構造化されたテキストファイル
構造を持つファイルを作成するには次の方法がある。
- セパレータ('\t',','など)を用いる
- タグを'<'や'>'で囲む:や
- 記号を用いる:など
- インデント:など
- その他
8.2.1 CSV
セパレータによりフィールドに区切られているファイルは、スプレッドシートやデータベースとのデータ交換形式としてよく使われる。読み込みには、
- 一部のファイルはカンマ以外に代替のセパレータを用いる場合がある。
- 一部のファイルはエスケープシーケンスを使っている。セパレータの文字がフィールド内で使われている可能性がある場合、フィールド全体をくぉーと文字で囲むか、セパレータの前に何らかのエスケープ文字を付ける。
- ファイル内の行末を表す文字がなどによりまちまちである。
- 第1行に列名が含まれている場合がある。
といった理由から、標準のモジュールを用いて読み込むのがよい。
############################# ### csvファイルの読み込み ### ############################# import csv villains = [ ['Doctor','No'], ['Rosa','Klebb'], ['Mister','Big'], ['Auric','Goldfinger'], ['Ernst','Brofeld'] ] # ファイルの作成 with open('villains', 'wt', newline="") as fout: csvout = csv.writer(fout) csvout.writerows(villains) # ファイルの読み込み with open('villains', 'rt') as fin: cin = csv.reader(fin) villains = [row for row in cin] print(villains) # 辞書型で読込 with open('villains', 'rt') as fin: cin = csv.DictReader(fin, fieldnames=('first','last')) villains = [row for row in cin] print(villains)
8.2.2 XML
は、プログラム間でデータ構造を交換すべく、階層構造やシーケンス、集合、その他の構造をテキストでエンコードする最も傑出したマークアップ形式である。
には
- タグは<文字から始まる。
- 空白は無視される。
- <>といった開始タグの後ろに他のコンテンツが続き、<>といった終了タグで締めくくる。
- タグは他のタグの中で何段階にもネストできる。
- 開始タグにオプションの属性を組み込める。
- タグは値を持つことができる。
- 値も子も持たないタグでも、<(タグ)/>という形でスラッシュを入れる場所を変えることでひとつのタグになる。
- データを置く場所に特別な規則が無い
といった重要な性質を持つ。
はデータフィードやメッセージとして使われることが多い。
アプローチや機能の異なる様々なライブラリが、の高い柔軟性の影響を受けている。最も簡単にを読み込むにはを使えばよい。
############################# ### XMLファイルの読み込み ### ############################# import xml.etree.ElementTree as et tree = et.ElementTree(file = r"C:\Users\Julie\Documents\menu.xml") root = tree.getroot() root.tag for child in root: print('tag:', child.tag, 'attributes:', child.attrib) for grandchild in child: print('\ttag:', grandchild.tag, 'attributes:', grandchild.attrib) len(root) len(root[0])
8.2.3 HTML
はの基本的なドキュメント形式である。問題は、その多くがの規制に厳密に従っていないことで、その構文解析が難しい。またの大部分は、データ交換よりも出力の成型を目的としている。は別の章で扱う。
8.2.4 JSON
はの枠を超えて広く使われ、で用いられることも多いデータ形式である。
という拡張子のファイルがのファイルである。
以下、前述のファイルの内容をにしてみる。
########################## ### JSONファイルの作成 ### ########################## # 以下のデータをJSONにする menu = {"breakfast": { "hours": "7-11", "items":{ "breakfast burritos":"$6.00", "pancakes":"$4.00" } }, "lunch" : { "hours": "11-3", "items":{ "hamburger":"$5.00", } }, "dinner":{ "hours": "3-10", "items":{ "spaghetti": "$6.00" } } } import json menu_json = json.dumps(menu) print(menu_json) # JSONをPythonデータ構造に戻す menu2 = json.loads(menu_json) print(menu2) # datetimeなど一部のオブジェクトをエンコード、デコードしようとするとエラーを起こす import datetime now =datetime.datetime.utcnow() print(now) try: json.dumps(now) except: print(type(now),"はJSONに変換できません")
8.2.5 YAML
は、と同様にキーと値を持つが、日付と時刻を始めとしてよりも多くのデータ型を処理する。標準ライブラリでは扱えず、を用いる。
import yaml with open('mcintyre.yaml', 'rt') as fin: text = fin.read() data = yaml.load(text) data['details'] len(data['poems'])
8.2.6 セキュリティに関する注意事項
ここまでで紹介してきたすべての形式は、オブジェクトをファイルに保存し、ファイルからオブジェクトを読み戻すために使用できる。しかしこのプロセスを悪用すると、セキュリティ問題を引き起こしかねない。
8.2.7 設定ファイル
殆どのプログラムは様々なオプションや設定を提供している。長い間使い続ける設定はどこかに保存しておく必要がある。手軽で整理されない独自の設定ファイル形式を用いたくなるが、それは控える。更に書き出しのプログラムと読込のプログラムの両方をメンテナンスしなければならなくなる。
たとえばモジュールを用いてスタイルのファイルを処理する。
8.2.8 pickleによるシリアライズ
ファイルにデータ構造を保存することをシリアライズという。などのデータ形式においてプログラムの全データ型をシリアライズするには、カスタムの変換器が必要になる。にはそのためのモジュールとしてモジュールを持つ。
ただしはオブジェクトを作成できるため、セキュリティ上の注意をする。信用できないファイルをデシリアライズしてはならない。
# pickleであればdatetime型も容易にアクセス可能 import pickle import datetime now1 = datetime.datemitme.utcnow() pickled = pickle.dumps(now1) now2 = pickle.loads(pickled) print(now1) print(now2) # 独自クラスやオブジェクトも処理可能 import pickle class Tiny(): def __str__(self): return 'tiny' obj1 = Tiny() print(obj1) print(str(obj1)) pickled = pickle.dumps(obj1) print(pickled) obj2 = pickle.loads(pickled) print(obj2) print(str(obj2))
*1:第2版が出ているものの初版しか持っていないのでこちらで。