「大人の教養・知識・気付き」を伸ばすブログ

一流の大人(ビジネスマン、政治家、リーダー…)として知っておきたい、教養・社会動向を意外なところから取り上げ学ぶことで“気付く力”を伸ばすブログです。データ分析・語学に力点を置いています。 →現在、コンサルタントの雛になるべく、少しずつ勉強中です(※2024年1月21日改訂)。

MENU

Pythonをゆっくりていねいに学ぶ(その22/X)

 Pythonを真面目にゆっくり学ぶべく

を参考に学んでいきます*1

8. ファイルの入出力

8.2 構造化されたテキストファイル

 構造を持つファイルを作成するには次の方法がある。

  • セパレータ('\t',','など)を用いる\mathrm{CSV}
  • タグを'<'や'>'で囲む:\mathrm{XML}\mathrm{HTML}
  • 記号を用いる:\mathrm{JSON}など
  • インデント:\mathrm{YAML}など
  • その他
8.2.1 CSV

 セパレータによりフィールドに区切られているファイルは、スプレッドシートやデータベースとのデータ交換形式としてよく使われる。読み込みには、

  • 一部のファイルはカンマ以外に代替のセパレータを用いる場合がある。
  • 一部のファイルはエスケープシーケンスを使っている。セパレータの文字がフィールド内で使われている可能性がある場合、フィールド全体をくぉーと文字で囲むか、セパレータの前に何らかのエスケープ文字を付ける。
  • ファイル内の行末を表す文字が\mathrm{OS}などによりまちまちである。
  • 第1行に列名が含まれている場合がある。

といった理由から、標準の\mathrm{csv}モジュールを用いて読み込むのがよい。

#############################
### 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

 \mathrm{XML}は、プログラム間でデータ構造を交換すべく、階層構造やシーケンス、集合、その他の構造をテキストでエンコードする最も傑出したマークアップ形式である。
 \mathrm{XML}には

  • タグは<文字から始まる。
  • 空白は無視される。
  • <\mathrm{menu}>といった開始タグの後ろに他のコンテンツが続き、<\mathrm{/menu}>といった終了タグで締めくくる。
  • タグは他のタグの中で何段階にもネストできる。
  • 開始タグにオプションの属性を組み込める。
  • タグは値を持つことができる。
  • 値も子も持たないタグでも、<(タグ)/>という形でスラッシュを入れる場所を変えることでひとつのタグになる。
  • データを置く場所に特別な規則が無い

といった重要な性質を持つ。

\mathrm{XML}はデータフィードやメッセージとして使われることが多い。
 アプローチや機能の異なる様々な\mathrm{Python}ライブラリが、\mathrm{XML}の高い柔軟性の影響を受けている。最も簡単に\mathrm{XML}を読み込むには\mathrm{ElementTree}を使えばよい。

#############################
### 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

 \mathrm{HTML}\mathrm{Web}の基本的なドキュメント形式である。問題は、その多くが\mathrm{HTML}の規制に厳密に従っていないことで、その構文解析が難しい。また\mathrm{HTML}の大部分は、データ交換よりも出力の成型を目的としている。\mathrm{HTML}は別の章で扱う。

8.2.4 JSON

 \mathrm{JSON}\mathrm{JavaScript}の枠を超えて広く使われ、\mathrm{Python}で用いられることも多いデータ形式である。
 \mathrm{.json}という拡張子のファイルが\mathrm{JSON}のファイルである。
 以下、前述の\mathrm{XML}ファイルの内容を\mathrm{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

 \mathrm{YAML}は、\mathrm{JSON}と同様にキーと値を持つが、日付と時刻を始めとして\mathrm{JSON}よりも多くのデータ型を処理する。標準ライブラリでは扱えず、\mathrm{PyYAML}を用いる。

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 設定ファイル

 殆どのプログラムは様々なオプションや設定を提供している。長い間使い続ける設定はどこかに保存しておく必要がある。手軽で整理されない独自の設定ファイル形式を用いたくなるが、それは控える。更に書き出しのプログラムと読込のプログラムの両方をメンテナンスしなければならなくなる。
 たとえば\mathrm{configparser}モジュールを用いて\mathrm{Windows}スタイルの\mathrm{.ini}ファイルを処理する。

8.2.8 pickleによるシリアライズ

 ファイルにデータ構造を保存することをシリアライズという。\mathrm{JSON}などのデータ形式において\mathrm{Python}プログラムの全データ型をシリアライズするには、カスタムの変換器が必要になる。\mathrm{Python}にはそのためのモジュールとして\mathrm{pickle}モジュールを持つ。
 ただし\mathrm{pickle}\mathrm{Python}オブジェクトを作成できるため、セキュリティ上の注意をする。信用できないファイルをデシリアライズしてはならない。

# 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版が出ているものの初版しか持っていないのでこちらで。

プライバシーポリシー お問い合わせ